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

Refactor BlockProcessor and EpochProcessor #8856

Merged
merged 2 commits into from
Nov 27, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
package tech.pegasys.teku.spec.logic.common.block;

import static com.google.common.base.Preconditions.checkArgument;
import static tech.pegasys.teku.spec.config.SpecConfig.FAR_FUTURE_EPOCH;

import com.google.common.annotations.VisibleForTesting;
import it.unimi.dsi.fastutil.ints.IntList;
Expand Down Expand Up @@ -54,7 +53,6 @@
import tech.pegasys.teku.spec.datastructures.operations.AttesterSlashing;
import tech.pegasys.teku.spec.datastructures.operations.Deposit;
import tech.pegasys.teku.spec.datastructures.operations.DepositData;
import tech.pegasys.teku.spec.datastructures.operations.DepositMessage;
import tech.pegasys.teku.spec.datastructures.operations.IndexedAttestation;
import tech.pegasys.teku.spec.datastructures.operations.ProposerSlashing;
import tech.pegasys.teku.spec.datastructures.operations.SignedVoluntaryExit;
Expand Down Expand Up @@ -682,7 +680,7 @@ private boolean batchVerifyDepositSignatures(final SszList<Deposit> deposits) {
final BLSPublicKey pubkey = deposit.getData().getPubkey();
publicKeys.add(List.of(pubkey));
messages.add(
computeDepositSigningRoot(
miscHelpers.computeDepositSigningRoot(
pubkey,
deposit.getData().getWithdrawalCredentials(),
deposit.getData().getAmount()));
Expand Down Expand Up @@ -760,34 +758,18 @@ public void applyDeposit(
// Verify the deposit signature (proof of possession) which is not checked by the deposit
// contract
if (signatureAlreadyVerified
|| isValidDepositSignature(pubkey, withdrawalCredentials, amount, signature)) {
addValidatorToRegistry(state, pubkey, withdrawalCredentials, amount);
|| miscHelpers.isValidDepositSignature(
pubkey, withdrawalCredentials, amount, signature)) {
beaconStateMutators.addValidatorToRegistry(state, pubkey, withdrawalCredentials, amount);
} else {
handleInvalidDeposit(pubkey, maybePubkeyToIndexMap);
}
} else {
applyDepositToValidatorIndex(
state,
withdrawalCredentials,
signatureAlreadyVerified,
existingIndex.get(),
amount,
pubkey,
signature);
// Increase balance by deposit amount
beaconStateMutators.increaseBalance(state, existingIndex.get(), amount);
}
}

protected void applyDepositToValidatorIndex(
final MutableBeaconState state,
final Bytes32 withdrawalCredentials,
final boolean signatureAlreadyVerified,
final int validatorIndex,
final UInt64 amount,
final BLSPublicKey pubkey,
final BLSSignature signature) {
beaconStateMutators.increaseBalance(state, validatorIndex, amount);
}

protected void handleInvalidDeposit(
final BLSPublicKey pubkey,
final Optional<Object2IntMap<BLSPublicKey>> maybePubkeyToIndexMap) {
Expand All @@ -799,55 +781,6 @@ protected void handleInvalidDeposit(
});
}

/** is_valid_deposit_signature */
protected 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;
}
}

private Bytes computeDepositSigningRoot(
final BLSPublicKey pubkey, final Bytes32 withdrawalCredentials, final UInt64 amount) {
final Bytes32 domain = miscHelpers.computeDomain(Domain.DEPOSIT);
final DepositMessage depositMessage = new DepositMessage(pubkey, withdrawalCredentials, amount);
return miscHelpers.computeSigningRoot(depositMessage, domain);
}

protected 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);
}

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);
}

@Override
public void processVoluntaryExits(
final MutableBeaconState state,
Expand Down Expand Up @@ -905,13 +838,6 @@ protected BlockValidationResult verifyVoluntaryExits(
return BlockValidationResult.SUCCESSFUL;
}

protected void processWithdrawalRequests(
final MutableBeaconState state,
final BeaconBlockBody beaconBlockBody,
final Supplier<ValidatorExitContext> validatorExitContextSupplier) {
// No WithdrawalRequests until Electra
}

@Override
public void processDepositRequests(
final MutableBeaconState state, final List<DepositRequest> depositRequests) {
Expand Down Expand Up @@ -952,13 +878,6 @@ protected void safelyProcess(final BlockProcessingAction action) throws BlockPro
}
}

protected void assertCondition(final boolean condition, final String errorMessage)
throws BlockProcessingException {
if (!condition) {
throw new BlockProcessingException(errorMessage);
}
}

public interface IndexedAttestationProvider {

IndexedAttestation getIndexedAttestation(final Attestation attestation);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@
import java.util.ArrayList;
import java.util.List;
import java.util.function.Supplier;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
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.SpecConfig;
import tech.pegasys.teku.spec.datastructures.state.Validator;
Expand All @@ -27,6 +31,8 @@
import tech.pegasys.teku.spec.datastructures.state.beaconstate.MutableBeaconState;

public class BeaconStateMutators {
private static final Logger LOG = LogManager.getLogger();

protected final SpecConfig specConfig;
protected final MiscHelpers miscHelpers;
private final BeaconStateAccessors beaconStateAccessors;
Expand Down Expand Up @@ -142,6 +148,22 @@ public Supplier<ValidatorExitContext> createValidatorExitContextSupplier(
return Suppliers.memoize(() -> createValidatorExitContext(state));
}

/**
* <a
* href="https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#deposits">add_validator_to_registry</a>
*/
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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@

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;
import static tech.pegasys.teku.spec.logic.common.helpers.MathHelpers.uintTo4Bytes;
Expand All @@ -27,6 +29,9 @@
import org.apache.tuweni.bytes.Bytes;
import org.apache.tuweni.bytes.Bytes32;
import org.apache.tuweni.units.bigints.UInt256;
import tech.pegasys.teku.bls.BLSPublicKey;
import tech.pegasys.teku.bls.BLSSignature;
import tech.pegasys.teku.bls.impl.BlsException;
import tech.pegasys.teku.infrastructure.bytes.Bytes4;
import tech.pegasys.teku.infrastructure.crypto.Hash;
import tech.pegasys.teku.infrastructure.crypto.Sha256;
Expand All @@ -37,10 +42,12 @@
import tech.pegasys.teku.kzg.KZG;
import tech.pegasys.teku.kzg.KZGCommitment;
import tech.pegasys.teku.spec.config.SpecConfig;
import tech.pegasys.teku.spec.constants.Domain;
import tech.pegasys.teku.spec.constants.NetworkConstants;
import tech.pegasys.teku.spec.datastructures.blobs.versions.deneb.BlobSidecar;
import tech.pegasys.teku.spec.datastructures.blocks.BeaconBlock;
import tech.pegasys.teku.spec.datastructures.blocks.SignedBeaconBlock;
import tech.pegasys.teku.spec.datastructures.operations.DepositMessage;
import tech.pegasys.teku.spec.datastructures.state.ForkData;
import tech.pegasys.teku.spec.datastructures.state.SigningData;
import tech.pegasys.teku.spec.datastructures.state.Validator;
Expand Down Expand Up @@ -326,6 +333,13 @@ public Bytes32 computeSigningRoot(final Bytes bytes, final Bytes32 domain) {
return domainWrappedObject.hashTreeRoot();
}

public Bytes computeDepositSigningRoot(
final BLSPublicKey pubkey, final Bytes32 withdrawalCredentials, final UInt64 amount) {
final Bytes32 domain = computeDomain(Domain.DEPOSIT);
final DepositMessage depositMessage = new DepositMessage(pubkey, withdrawalCredentials, amount);
return computeSigningRoot(depositMessage, domain);
}

public Bytes4 computeForkDigest(
final Bytes4 currentVersion, final Bytes32 genesisValidatorsRoot) {
return new Bytes4(computeForkDataRoot(currentVersion, genesisValidatorsRoot).slice(0, 4));
Expand Down Expand Up @@ -400,6 +414,38 @@ 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<MiscHelpersDeneb> toVersionDeneb() {
return Optional.empty();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -213,20 +213,6 @@ public Optional<UInt64> processAttestationProposerReward(
return Optional.empty();
}

@Override
protected void addValidatorToRegistry(
final MutableBeaconState state,
final BLSPublicKey pubkey,
final Bytes32 withdrawalCredentials,
final UInt64 amount) {
super.addValidatorToRegistry(state, pubkey, withdrawalCredentials, amount);
final MutableBeaconStateAltair stateAltair = MutableBeaconStateAltair.required(state);

stateAltair.getPreviousEpochParticipation().append(SszByte.ZERO);
stateAltair.getCurrentEpochParticipation().append(SszByte.ZERO);
stateAltair.getInactivityScores().append(SszUInt64.ZERO);
}

@Override
public void processSyncAggregate(
final MutableBeaconState baseState,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,15 @@
import static tech.pegasys.teku.spec.constants.IncentivizationWeights.WEIGHT_DENOMINATOR;

import java.util.function.Supplier;
import org.apache.tuweni.bytes.Bytes32;
import tech.pegasys.teku.bls.BLSPublicKey;
import tech.pegasys.teku.infrastructure.ssz.primitive.SszByte;
import tech.pegasys.teku.infrastructure.ssz.primitive.SszUInt64;
import tech.pegasys.teku.infrastructure.unsigned.UInt64;
import tech.pegasys.teku.spec.config.SpecConfigAltair;
import tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconStateCache;
import tech.pegasys.teku.spec.datastructures.state.beaconstate.MutableBeaconState;
import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.altair.MutableBeaconStateAltair;
import tech.pegasys.teku.spec.logic.common.helpers.BeaconStateAccessors;
import tech.pegasys.teku.spec.logic.common.helpers.BeaconStateMutators;
import tech.pegasys.teku.spec.logic.common.helpers.MiscHelpers;
Expand All @@ -36,6 +41,20 @@ public BeaconStateMutatorsAltair(
this.specConfigAltair = specConfig;
}

@Override
public void addValidatorToRegistry(
final MutableBeaconState state,
final BLSPublicKey pubkey,
final Bytes32 withdrawalCredentials,
final UInt64 amount) {
super.addValidatorToRegistry(state, pubkey, withdrawalCredentials, amount);
final MutableBeaconStateAltair stateAltair = MutableBeaconStateAltair.required(state);

stateAltair.getPreviousEpochParticipation().append(SszByte.ZERO);
stateAltair.getCurrentEpochParticipation().append(SszByte.ZERO);
stateAltair.getInactivityScores().append(SszUInt64.ZERO);
}

@Override
protected UInt64 calculateProposerReward(final UInt64 whistleblowerReward) {
return whistleblowerReward.times(PROPOSER_WEIGHT).dividedBy(WEIGHT_DENOMINATOR);
Expand Down
Loading