Search in sources :

Example 1 with AsyncBatchBLSSignatureVerifier

use of tech.pegasys.teku.spec.logic.common.util.AsyncBatchBLSSignatureVerifier in project teku by ConsenSys.

the class SignedContributionAndProofValidator method validateWithState.

private SafeFuture<InternalValidationResult> validateWithState(final SignedContributionAndProof proof, final ContributionAndProof contributionAndProof, final SyncCommitteeContribution contribution, final SyncCommitteeUtil syncCommitteeUtil, final UniquenessKey uniquenessKey, final BeaconStateAltair state) {
    final BeaconStateAccessors beaconStateAccessors = spec.atSlot(contribution.getSlot()).beaconStateAccessors();
    final Optional<BLSPublicKey> aggregatorPublicKey = beaconStateAccessors.getValidatorPubKey(state, contributionAndProof.getAggregatorIndex());
    if (aggregatorPublicKey.isEmpty()) {
        return futureFailureResult("Rejecting proof because aggregator index %s is an unknown validator", contributionAndProof.getAggregatorIndex());
    }
    final UInt64 contributionEpoch = syncCommitteeUtil.getEpochForDutiesAtSlot(contribution.getSlot());
    // state.current_sync_committee.pubkeys.
    if (!isInSyncSubcommittee(syncCommitteeUtil, contribution, state, contributionEpoch, contributionAndProof.getAggregatorIndex())) {
        return futureFailureResult("Rejecting proof because aggregator index %s is not in the current sync subcommittee", contributionAndProof.getAggregatorIndex());
    }
    // contribution.slot, contribution_and_proof.selection_proof) returns True.
    if (!syncCommitteeUtil.isSyncCommitteeAggregator(contributionAndProof.getSelectionProof())) {
        return futureFailureResult("Rejecting proof because selection proof %s is not an aggregator", contributionAndProof.getSelectionProof());
    }
    final AsyncBatchBLSSignatureVerifier signatureVerifier = new AsyncBatchBLSSignatureVerifier(this.signatureVerifier);
    // [REJECT] The contribution_and_proof.selection_proof is a valid signature of the
    // contribution.slot by the validator with index
    // contribution_and_proof.aggregator_index.
    final Bytes signingRoot = syncCommitteeUtil.getSyncAggregatorSelectionDataSigningRoot(syncCommitteeUtil.createSyncAggregatorSelectionData(contribution.getSlot(), contribution.getSubcommitteeIndex()), state.getForkInfo());
    if (!signatureVerifier.verify(aggregatorPublicKey.get(), signingRoot, contributionAndProof.getSelectionProof())) {
        return futureFailureResult("Rejecting proof at slot %s for subcommittee index %s because selection proof is invalid", contribution.getSlot(), contribution.getSubcommitteeIndex());
    }
    // valid.
    if (!signatureVerifier.verify(aggregatorPublicKey.get(), syncCommitteeUtil.getContributionAndProofSigningRoot(state, contributionAndProof), proof.getSignature())) {
        return futureFailureResult("Rejecting proof %s because aggregator signature is invalid", proof.getSignature());
    }
    final SpecConfigAltair config = SpecConfigAltair.required(spec.getSpecConfig(contributionEpoch));
    final SyncCommittee syncCommittee = syncCommitteeUtil.getSyncCommittee(state, contributionEpoch);
    final int subcommitteeSize = config.getSyncCommitteeSize() / SYNC_COMMITTEE_SUBNET_COUNT;
    // [REJECT] The aggregate signature is valid for the message beacon_block_root and
    // aggregate pubkey derived from the participation info in aggregation_bits for the
    // subcommittee specified by the subcommittee_index.
    final List<BLSPublicKey> contributorPublicKeys = contribution.getAggregationBits().streamAllSetBits().mapToObj(participantIndex -> getParticipantPublicKey(state, syncCommittee, contribution, subcommitteeSize, participantIndex)).collect(Collectors.toList());
    if (!signatureVerifier.verify(contributorPublicKeys, syncCommitteeUtil.getSyncCommitteeMessageSigningRoot(contribution.getBeaconBlockRoot(), contributionEpoch, state.getForkInfo()), contribution.getSignature())) {
        return futureFailureResult("Rejecting proof because aggregate signature %s is invalid", contribution.getSignature());
    }
    return signatureVerifier.batchVerify().thenApply(signatureValid -> {
        if (!signatureValid) {
            return failureResult("Rejecting proof with signature %s because batch signature check failed", contribution.getSignature());
        }
        if (!seenIndices.add(uniquenessKey)) {
            // Got added by another thread while we were validating it
            return IGNORE;
        }
        return ACCEPT;
    });
}
Also used : AsyncBLSSignatureVerifier(tech.pegasys.teku.spec.logic.common.util.AsyncBLSSignatureVerifier) TimeProvider(tech.pegasys.teku.infrastructure.time.TimeProvider) SafeFuture(tech.pegasys.teku.infrastructure.async.SafeFuture) BeaconStateAccessors(tech.pegasys.teku.spec.logic.common.helpers.BeaconStateAccessors) IGNORE(tech.pegasys.teku.statetransition.validation.InternalValidationResult.IGNORE) Bytes(org.apache.tuweni.bytes.Bytes) ContributionAndProof(tech.pegasys.teku.spec.datastructures.operations.versions.altair.ContributionAndProof) SYNC_COMMITTEE_SUBNET_COUNT(tech.pegasys.teku.spec.constants.NetworkConstants.SYNC_COMMITTEE_SUBNET_COUNT) LimitedSet(tech.pegasys.teku.infrastructure.collections.LimitedSet) FormatMethod(com.google.errorprone.annotations.FormatMethod) SyncCommitteeUtil(tech.pegasys.teku.spec.logic.common.util.SyncCommitteeUtil) UInt64(tech.pegasys.teku.infrastructure.unsigned.UInt64) Spec(tech.pegasys.teku.spec.Spec) ACCEPT(tech.pegasys.teku.statetransition.validation.InternalValidationResult.ACCEPT) SyncCommitteeContribution(tech.pegasys.teku.spec.datastructures.operations.versions.altair.SyncCommitteeContribution) BLSPublicKey(tech.pegasys.teku.bls.BLSPublicKey) Set(java.util.Set) ValidationResultCode(tech.pegasys.teku.statetransition.validation.ValidationResultCode) Collectors(java.util.stream.Collectors) SignedContributionAndProof(tech.pegasys.teku.spec.datastructures.operations.versions.altair.SignedContributionAndProof) Objects(java.util.Objects) SyncCommittee(tech.pegasys.teku.spec.datastructures.state.SyncCommittee) List(java.util.List) VALID_CONTRIBUTION_AND_PROOF_SET_SIZE(tech.pegasys.teku.spec.config.Constants.VALID_CONTRIBUTION_AND_PROOF_SET_SIZE) Logger(org.apache.logging.log4j.Logger) RecentChainData(tech.pegasys.teku.storage.client.RecentChainData) Optional(java.util.Optional) AsyncBatchBLSSignatureVerifier(tech.pegasys.teku.spec.logic.common.util.AsyncBatchBLSSignatureVerifier) BeaconStateAltair(tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.altair.BeaconStateAltair) LogManager(org.apache.logging.log4j.LogManager) InternalValidationResult(tech.pegasys.teku.statetransition.validation.InternalValidationResult) SpecConfigAltair(tech.pegasys.teku.spec.config.SpecConfigAltair) BeaconState(tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconState) Bytes(org.apache.tuweni.bytes.Bytes) AsyncBatchBLSSignatureVerifier(tech.pegasys.teku.spec.logic.common.util.AsyncBatchBLSSignatureVerifier) BeaconStateAccessors(tech.pegasys.teku.spec.logic.common.helpers.BeaconStateAccessors) BLSPublicKey(tech.pegasys.teku.bls.BLSPublicKey) UInt64(tech.pegasys.teku.infrastructure.unsigned.UInt64) SyncCommittee(tech.pegasys.teku.spec.datastructures.state.SyncCommittee) SpecConfigAltair(tech.pegasys.teku.spec.config.SpecConfigAltair)

Example 2 with AsyncBatchBLSSignatureVerifier

use of tech.pegasys.teku.spec.logic.common.util.AsyncBatchBLSSignatureVerifier in project teku by ConsenSys.

the class AggregateAttestationValidator method validate.

public SafeFuture<InternalValidationResult> validate(final ValidateableAttestation attestation) {
    final SignedAggregateAndProof signedAggregate = attestation.getSignedAggregateAndProof();
    final AggregateAndProof aggregateAndProof = signedAggregate.getMessage();
    final Attestation aggregate = aggregateAndProof.getAggregate();
    final UInt64 aggregateSlot = aggregate.getData().getSlot();
    final SpecVersion specVersion = spec.atSlot(aggregateSlot);
    final AggregatorIndexAndEpoch aggregatorIndexAndEpoch = new AggregatorIndexAndEpoch(aggregateAndProof.getIndex(), spec.computeEpochAtSlot(aggregateSlot));
    if (receivedAggregatorIndexAndEpochs.contains(aggregatorIndexAndEpoch)) {
        return completedFuture(ignore("Ignoring duplicate aggregate"));
    }
    if (receivedValidAggregations.contains(attestation.hash_tree_root())) {
        return completedFuture(ignore("Ignoring duplicate aggregate based on hash tree root"));
    }
    final AsyncBatchBLSSignatureVerifier signatureVerifier = new AsyncBatchBLSSignatureVerifier(this.signatureVerifier);
    return singleOrAggregateAttestationChecks(signatureVerifier, attestation, OptionalInt.empty()).thenCompose(aggregateInternalValidationResult -> {
        if (aggregateInternalValidationResult.isNotProcessable()) {
            LOG.trace("Rejecting aggregate because attestation failed validation");
            return completedFuture(aggregateInternalValidationResult);
        }
        return recentChainData.retrieveBlockState(aggregate.getData().getBeacon_block_root()).thenCompose(maybeState -> maybeState.isEmpty() ? completedFuture(Optional.empty()) : attestationValidator.resolveStateForAttestation(aggregate, maybeState.get())).thenCompose(maybeState -> {
            if (maybeState.isEmpty()) {
                return SafeFuture.completedFuture(InternalValidationResult.SAVE_FOR_FUTURE);
            }
            final BeaconState state = maybeState.get();
            final Optional<BLSPublicKey> aggregatorPublicKey = spec.getValidatorPubKey(state, aggregateAndProof.getIndex());
            if (aggregatorPublicKey.isEmpty()) {
                return SafeFuture.completedFuture(reject("Rejecting aggregate with invalid index"));
            }
            if (!isSelectionProofValid(signatureVerifier, aggregateSlot, state, aggregatorPublicKey.get(), aggregateAndProof.getSelection_proof())) {
                return SafeFuture.completedFuture(reject("Rejecting aggregate with incorrect selection proof"));
            }
            final IntList beaconCommittee = spec.getBeaconCommittee(state, aggregateSlot, aggregate.getData().getIndex());
            final int aggregatorModulo = specVersion.getValidatorsUtil().getAggregatorModulo(beaconCommittee.size());
            if (!specVersion.getValidatorsUtil().isAggregator(aggregateAndProof.getSelection_proof(), aggregatorModulo)) {
                return SafeFuture.completedFuture(reject("Rejecting aggregate because selection proof does not select validator as aggregator"));
            }
            if (!beaconCommittee.contains(toIntExact(aggregateAndProof.getIndex().longValue()))) {
                return SafeFuture.completedFuture(reject("Rejecting aggregate because attester is not in committee. Should have been one of %s", beaconCommittee));
            }
            if (!validateSignature(signatureVerifier, signedAggregate, state, aggregatorPublicKey.get())) {
                return SafeFuture.completedFuture(reject("Rejecting aggregate with invalid signature"));
            }
            return signatureVerifier.batchVerify().thenApply(signatureValid -> {
                if (!signatureValid) {
                    return reject("Rejecting aggregate with invalid batch signature");
                }
                if (!receivedAggregatorIndexAndEpochs.add(aggregatorIndexAndEpoch)) {
                    return ignore("Ignoring duplicate aggregate");
                }
                if (!receivedValidAggregations.add(attestation.hash_tree_root())) {
                    return ignore("Ignoring duplicate aggregate based on hash tree root");
                }
                return aggregateInternalValidationResult;
            });
        });
    });
}
Also used : AsyncBLSSignatureVerifier(tech.pegasys.teku.spec.logic.common.util.AsyncBLSSignatureVerifier) AggregateAndProof(tech.pegasys.teku.spec.datastructures.operations.AggregateAndProof) SafeFuture(tech.pegasys.teku.infrastructure.async.SafeFuture) Bytes(org.apache.tuweni.bytes.Bytes) SafeFuture.completedFuture(tech.pegasys.teku.infrastructure.async.SafeFuture.completedFuture) OptionalInt(java.util.OptionalInt) BLSSignatureVerifier(tech.pegasys.teku.bls.BLSSignatureVerifier) SpecVersion(tech.pegasys.teku.spec.SpecVersion) LimitedSet(tech.pegasys.teku.infrastructure.collections.LimitedSet) SignedAggregateAndProof(tech.pegasys.teku.spec.datastructures.operations.SignedAggregateAndProof) VALID_AGGREGATE_SET_SIZE(tech.pegasys.teku.spec.config.Constants.VALID_AGGREGATE_SET_SIZE) UInt64(tech.pegasys.teku.infrastructure.unsigned.UInt64) Math.toIntExact(java.lang.Math.toIntExact) Spec(tech.pegasys.teku.spec.Spec) Bytes32(org.apache.tuweni.bytes.Bytes32) Attestation(tech.pegasys.teku.spec.datastructures.operations.Attestation) Domain(tech.pegasys.teku.spec.constants.Domain) BLSSignature(tech.pegasys.teku.bls.BLSSignature) InternalValidationResult.ignore(tech.pegasys.teku.statetransition.validation.InternalValidationResult.ignore) BLSPublicKey(tech.pegasys.teku.bls.BLSPublicKey) Set(java.util.Set) Objects(java.util.Objects) InternalValidationResult.reject(tech.pegasys.teku.statetransition.validation.InternalValidationResult.reject) IntList(it.unimi.dsi.fastutil.ints.IntList) Logger(org.apache.logging.log4j.Logger) RecentChainData(tech.pegasys.teku.storage.client.RecentChainData) ValidateableAttestation(tech.pegasys.teku.spec.datastructures.attestation.ValidateableAttestation) Optional(java.util.Optional) AsyncBatchBLSSignatureVerifier(tech.pegasys.teku.spec.logic.common.util.AsyncBatchBLSSignatureVerifier) LogManager(org.apache.logging.log4j.LogManager) BeaconState(tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconState) Attestation(tech.pegasys.teku.spec.datastructures.operations.Attestation) ValidateableAttestation(tech.pegasys.teku.spec.datastructures.attestation.ValidateableAttestation) BeaconState(tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconState) IntList(it.unimi.dsi.fastutil.ints.IntList) SpecVersion(tech.pegasys.teku.spec.SpecVersion) AsyncBatchBLSSignatureVerifier(tech.pegasys.teku.spec.logic.common.util.AsyncBatchBLSSignatureVerifier) SignedAggregateAndProof(tech.pegasys.teku.spec.datastructures.operations.SignedAggregateAndProof) UInt64(tech.pegasys.teku.infrastructure.unsigned.UInt64) BLSPublicKey(tech.pegasys.teku.bls.BLSPublicKey) AggregateAndProof(tech.pegasys.teku.spec.datastructures.operations.AggregateAndProof) SignedAggregateAndProof(tech.pegasys.teku.spec.datastructures.operations.SignedAggregateAndProof)

Aggregations

Objects (java.util.Objects)2 Optional (java.util.Optional)2 Set (java.util.Set)2 LogManager (org.apache.logging.log4j.LogManager)2 Logger (org.apache.logging.log4j.Logger)2 Bytes (org.apache.tuweni.bytes.Bytes)2 BLSPublicKey (tech.pegasys.teku.bls.BLSPublicKey)2 SafeFuture (tech.pegasys.teku.infrastructure.async.SafeFuture)2 LimitedSet (tech.pegasys.teku.infrastructure.collections.LimitedSet)2 UInt64 (tech.pegasys.teku.infrastructure.unsigned.UInt64)2 Spec (tech.pegasys.teku.spec.Spec)2 BeaconState (tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconState)2 AsyncBLSSignatureVerifier (tech.pegasys.teku.spec.logic.common.util.AsyncBLSSignatureVerifier)2 AsyncBatchBLSSignatureVerifier (tech.pegasys.teku.spec.logic.common.util.AsyncBatchBLSSignatureVerifier)2 RecentChainData (tech.pegasys.teku.storage.client.RecentChainData)2 FormatMethod (com.google.errorprone.annotations.FormatMethod)1 IntList (it.unimi.dsi.fastutil.ints.IntList)1 Math.toIntExact (java.lang.Math.toIntExact)1 List (java.util.List)1 OptionalInt (java.util.OptionalInt)1