From e2be7d4cb2f06f5b9d909f107f41b0d41cc78ad1 Mon Sep 17 00:00:00 2001 From: Stefan Bratanov Date: Tue, 10 Dec 2024 16:49:36 +0000 Subject: [PATCH] Change consolidating balance calculation + small refactor --- .../spec/constants/WithdrawalPrefixes.java | 1 - .../common/helpers/BeaconStateMutators.java | 49 +++++++++----- .../logic/common/helpers/MiscHelpers.java | 47 ++++--------- .../electra/block/BlockProcessorElectra.java | 66 +++++++++---------- .../helpers/BeaconStateAccessorsElectra.java | 3 +- .../helpers/BeaconStateMutatorsElectra.java | 25 +++++++ .../electra/helpers/MiscHelpersElectra.java | 37 ++--------- .../epoch/EpochProcessorElectra.java | 2 + 8 files changed, 113 insertions(+), 117 deletions(-) diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/constants/WithdrawalPrefixes.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/constants/WithdrawalPrefixes.java index d2bd4b0cedd..5919e41cd8e 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/constants/WithdrawalPrefixes.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/constants/WithdrawalPrefixes.java @@ -20,5 +20,4 @@ public class WithdrawalPrefixes { 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); } diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/common/helpers/BeaconStateMutators.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/common/helpers/BeaconStateMutators.java index 628e5ff437d..fd20e98dbf1 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/common/helpers/BeaconStateMutators.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/common/helpers/BeaconStateMutators.java @@ -148,22 +148,6 @@ public Supplier createValidatorExitContextSupplier( return Suppliers.memoize(() -> createValidatorExitContext(state)); } - /** - * add_validator_to_registry - */ - public void addValidatorToRegistry( - final MutableBeaconState state, - final BLSPublicKey pubkey, - final Bytes32 withdrawalCredentials, - final UInt64 amount) { - final Validator validator = - miscHelpers.getValidatorFromDeposit(pubkey, withdrawalCredentials, amount); - LOG.debug("Adding new validator with index {} to state", state.getValidators().size()); - state.getValidators().append(validator); - state.getBalances().appendElement(amount); - } - /** * This function implements an optimized version of exitQueueEpoch and exitQueueChurn calculation, * compared to the `initiate_validator_exit` reference implementation. @@ -239,6 +223,21 @@ public void setExitQueueChurn(final UInt64 exitQueueChurn) { } } + /** + * add_validator_to_registry + */ + public void addValidatorToRegistry( + final MutableBeaconState state, + final BLSPublicKey pubkey, + final Bytes32 withdrawalCredentials, + final UInt64 amount) { + final Validator validator = getValidatorFromDeposit(pubkey, withdrawalCredentials, amount); + LOG.debug("Adding new validator with index {} to state", state.getValidators().size()); + state.getValidators().append(validator); + state.getBalances().appendElement(amount); + } + public void slashValidator( final MutableBeaconState state, final int slashedIndex, @@ -305,4 +304,22 @@ protected int getMinSlashingPenaltyQuotient() { protected int getWhistleblowerRewardQuotient() { return specConfig.getWhistleblowerRewardQuotient(); } + + /** get_validator_from_deposit */ + protected Validator getValidatorFromDeposit( + final BLSPublicKey pubkey, final Bytes32 withdrawalCredentials, final UInt64 amount) { + final UInt64 effectiveBalance = + amount + .minus(amount.mod(specConfig.getEffectiveBalanceIncrement())) + .min(specConfig.getMaxEffectiveBalance()); + return new Validator( + pubkey, + withdrawalCredentials, + effectiveBalance, + false, + FAR_FUTURE_EPOCH, + FAR_FUTURE_EPOCH, + FAR_FUTURE_EPOCH, + FAR_FUTURE_EPOCH); + } } 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 559f3a01c87..00b40f16243 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 @@ -15,7 +15,6 @@ import static com.google.common.base.Preconditions.checkArgument; import static tech.pegasys.teku.infrastructure.crypto.Hash.getSha256Instance; -import static tech.pegasys.teku.spec.config.SpecConfig.FAR_FUTURE_EPOCH; import static tech.pegasys.teku.spec.logic.common.block.AbstractBlockProcessor.depositSignatureVerifier; import static tech.pegasys.teku.spec.logic.common.helpers.MathHelpers.bytesToUInt64; import static tech.pegasys.teku.spec.logic.common.helpers.MathHelpers.uint64ToBytes; @@ -364,6 +363,20 @@ private Bytes32 computeForkDataRoot( return new ForkData(currentVersion, genesisValidatorsRoot).hashTreeRoot(); } + /** is_valid_deposit_signature */ + public boolean isValidDepositSignature( + final BLSPublicKey pubkey, + final Bytes32 withdrawalCredentials, + final UInt64 amount, + final BLSSignature signature) { + try { + return depositSignatureVerifier.verify( + pubkey, computeDepositSigningRoot(pubkey, withdrawalCredentials, amount), signature); + } catch (final BlsException e) { + return false; + } + } + public boolean isMergeTransitionComplete(final BeaconState state) { return false; } @@ -414,38 +427,6 @@ public boolean isFormerDepositMechanismDisabled(final BeaconState state) { return false; } - /** is_valid_deposit_signature */ - public boolean isValidDepositSignature( - final BLSPublicKey pubkey, - final Bytes32 withdrawalCredentials, - final UInt64 amount, - final BLSSignature signature) { - try { - return depositSignatureVerifier.verify( - pubkey, computeDepositSigningRoot(pubkey, withdrawalCredentials, amount), signature); - } catch (final BlsException e) { - return false; - } - } - - /** get_validator_from_deposit */ - public Validator getValidatorFromDeposit( - final BLSPublicKey pubkey, final Bytes32 withdrawalCredentials, final UInt64 amount) { - final UInt64 effectiveBalance = - amount - .minus(amount.mod(specConfig.getEffectiveBalanceIncrement())) - .min(specConfig.getMaxEffectiveBalance()); - return new Validator( - pubkey, - withdrawalCredentials, - effectiveBalance, - false, - FAR_FUTURE_EPOCH, - FAR_FUTURE_EPOCH, - FAR_FUTURE_EPOCH, - FAR_FUTURE_EPOCH); - } - public Optional toVersionDeneb() { 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 8693f37efc0..375e2b6dd0d 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 @@ -164,10 +164,10 @@ protected void processOperationsNoValidation( final ExecutionRequests executionRequests = BeaconBlockBodyElectra.required(body).getExecutionRequests(); - this.processDepositRequests(state, executionRequests.getDeposits()); - this.processWithdrawalRequests( + processDepositRequests(state, executionRequests.getDeposits()); + processWithdrawalRequests( state, executionRequests.getWithdrawals(), validatorExitContextSupplier); - this.processConsolidationRequests(state, executionRequests.getConsolidations()); + processConsolidationRequests(state, executionRequests.getConsolidations()); }); } @@ -210,6 +210,36 @@ public void processWithdrawals( specConfigElectra); } + /* + Implements process_deposit_request from consensus-specs (EIP-6110) + */ + @Override + public void processDepositRequests( + final MutableBeaconState state, final List depositRequests) { + final MutableBeaconStateElectra electraState = MutableBeaconStateElectra.required(state); + final SszMutableList pendingDeposits = + MutableBeaconStateElectra.required(state).getPendingDeposits(); + for (DepositRequest depositRequest : depositRequests) { + // process_deposit_request + if (electraState + .getDepositRequestsStartIndex() + .equals(SpecConfigElectra.UNSET_DEPOSIT_REQUESTS_START_INDEX)) { + electraState.setDepositRequestsStartIndex(depositRequest.getIndex()); + } + + final PendingDeposit deposit = + schemaDefinitionsElectra + .getPendingDepositSchema() + .create( + new SszPublicKey(depositRequest.getPubkey()), + SszBytes32.of(depositRequest.getWithdrawalCredentials()), + SszUInt64.of(depositRequest.getAmount()), + new SszSignature(depositRequest.getSignature()), + SszUInt64.of(state.getSlot())); + pendingDeposits.append(deposit); + } + } + /** Implements process_withdrawal_request from consensus-specs (EIP-7002 & EIP-7251). */ @Override public void processWithdrawalRequests( @@ -360,36 +390,6 @@ public void processWithdrawalRequests( }); } - /* - Implements process_deposit_request from consensus-specs (EIP-6110) - */ - @Override - public void processDepositRequests( - final MutableBeaconState state, final List depositRequests) { - final MutableBeaconStateElectra electraState = MutableBeaconStateElectra.required(state); - final SszMutableList pendingDeposits = - MutableBeaconStateElectra.required(state).getPendingDeposits(); - for (DepositRequest depositRequest : depositRequests) { - // process_deposit_request - if (electraState - .getDepositRequestsStartIndex() - .equals(SpecConfigElectra.UNSET_DEPOSIT_REQUESTS_START_INDEX)) { - electraState.setDepositRequestsStartIndex(depositRequest.getIndex()); - } - - final PendingDeposit deposit = - schemaDefinitionsElectra - .getPendingDepositSchema() - .create( - new SszPublicKey(depositRequest.getPubkey()), - SszBytes32.of(depositRequest.getWithdrawalCredentials()), - SszUInt64.of(depositRequest.getAmount()), - new SszSignature(depositRequest.getSignature()), - SszUInt64.of(state.getSlot())); - pendingDeposits.append(deposit); - } - } - /** * Implements process_consolidation_request from consensus-spec (EIP-7251) * 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 2bc48d0ba4f..a4dc616877f 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,9 +60,8 @@ 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 = miscHelpers.getMaxEffectiveBalance(validator); final UInt64 validatorBalance = state.getBalances().get(validatorIndex).get(); - return validatorBalance.min(maxEffectiveBalance); + return validatorBalance.min(validator.getEffectiveBalance()); } /** diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/electra/helpers/BeaconStateMutatorsElectra.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/electra/helpers/BeaconStateMutatorsElectra.java index 7b9e7b2a1ba..1325dab899a 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/electra/helpers/BeaconStateMutatorsElectra.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/electra/helpers/BeaconStateMutatorsElectra.java @@ -14,11 +14,13 @@ package tech.pegasys.teku.spec.logic.versions.electra.helpers; import static com.google.common.base.Preconditions.checkArgument; +import static tech.pegasys.teku.infrastructure.unsigned.UInt64.ZERO; import static tech.pegasys.teku.spec.config.SpecConfig.FAR_FUTURE_EPOCH; import static tech.pegasys.teku.spec.constants.WithdrawalPrefixes.COMPOUNDING_WITHDRAWAL_BYTE; import java.util.function.Supplier; import org.apache.tuweni.bytes.Bytes32; +import tech.pegasys.teku.bls.BLSPublicKey; import tech.pegasys.teku.bls.BLSSignature; import tech.pegasys.teku.infrastructure.ssz.primitive.SszBytes32; import tech.pegasys.teku.infrastructure.ssz.primitive.SszUInt64; @@ -268,4 +270,27 @@ protected int getWhistleblowerRewardQuotient() { protected int getMinSlashingPenaltyQuotient() { return specConfigElectra.getMinSlashingPenaltyQuotientElectra(); } + + @Override + protected Validator getValidatorFromDeposit( + final BLSPublicKey pubkey, final Bytes32 withdrawalCredentials, final UInt64 amount) { + final Validator validator = + new Validator( + pubkey, + withdrawalCredentials, + ZERO, + false, + FAR_FUTURE_EPOCH, + FAR_FUTURE_EPOCH, + FAR_FUTURE_EPOCH, + FAR_FUTURE_EPOCH); + + final UInt64 maxEffectiveBalance = miscHelpers.getMaxEffectiveBalance(validator); + final UInt64 validatorEffectiveBalance = + amount + .minusMinZero(amount.mod(specConfig.getEffectiveBalanceIncrement())) + .min(maxEffectiveBalance); + + return validator.withEffectiveBalance(validatorEffectiveBalance); + } } 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 52f05f74dea..fdb4303afa1 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 @@ -13,13 +13,9 @@ package tech.pegasys.teku.spec.logic.versions.electra.helpers; -import static tech.pegasys.teku.infrastructure.unsigned.UInt64.ZERO; -import static tech.pegasys.teku.spec.config.SpecConfig.FAR_FUTURE_EPOCH; - import it.unimi.dsi.fastutil.ints.IntList; import java.util.Optional; import org.apache.tuweni.bytes.Bytes32; -import tech.pegasys.teku.bls.BLSPublicKey; import tech.pegasys.teku.infrastructure.unsigned.UInt64; import tech.pegasys.teku.spec.config.SpecConfigDeneb; import tech.pegasys.teku.spec.config.SpecConfigElectra; @@ -75,34 +71,6 @@ public UInt64 getMaxEffectiveBalance(final Validator validator) { : specConfigElectra.getMinActivationBalance(); } - @Override - public Validator getValidatorFromDeposit( - final BLSPublicKey pubkey, final Bytes32 withdrawalCredentials, final UInt64 amount) { - final Validator validator = - new Validator( - pubkey, - withdrawalCredentials, - ZERO, - false, - FAR_FUTURE_EPOCH, - FAR_FUTURE_EPOCH, - FAR_FUTURE_EPOCH, - FAR_FUTURE_EPOCH); - - final UInt64 maxEffectiveBalance = getMaxEffectiveBalance(validator); - final UInt64 validatorEffectiveBalance = - amount - .minusMinZero(amount.mod(specConfig.getEffectiveBalanceIncrement())) - .min(maxEffectiveBalance); - - return validator.withEffectiveBalance(validatorEffectiveBalance); - } - - @Override - public Optional toVersionElectra() { - return Optional.of(this); - } - @Override public boolean isFormerDepositMechanismDisabled(final BeaconState state) { // if the next deposit to be processed by Eth1Data poll has the index of the first deposit @@ -112,4 +80,9 @@ public boolean isFormerDepositMechanismDisabled(final BeaconState state) { .getEth1DepositIndex() .equals(BeaconStateElectra.required(state).getDepositRequestsStartIndex()); } + + @Override + public Optional toVersionElectra() { + return Optional.of(this); + } } 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 8eedf3e372e..0852fcdc7d4 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 @@ -322,8 +322,10 @@ public void processPendingConsolidations(final MutableBeaconState state) { break; } + // Calculate the consolidated balance final UInt64 activeBalance = stateAccessorsElectra.getActiveBalance(state, pendingConsolidation.getSourceIndex()); + // Move active balance to target. Excess balance is withdrawable. beaconStateMutators.decreaseBalance( state, pendingConsolidation.getSourceIndex(), activeBalance); beaconStateMutators.increaseBalance(