Search in sources :

Example 1 with ATTESTATION_PROPAGATION_SLOT_RANGE

use of tech.pegasys.teku.spec.config.Constants.ATTESTATION_PROPAGATION_SLOT_RANGE in project teku by ConsenSys.

the class AttestationValidator method singleOrAggregateAttestationChecks.

SafeFuture<InternalValidationResult> singleOrAggregateAttestationChecks(final AsyncBLSSignatureVerifier signatureVerifier, final ValidateableAttestation validateableAttestation, final OptionalInt receivedOnSubnetId) {
    Attestation attestation = validateableAttestation.getAttestation();
    final AttestationData data = attestation.getData();
    // The attestation's epoch matches its target
    if (!data.getTarget().getEpoch().equals(spec.computeEpochAtSlot(data.getSlot()))) {
        return completedFuture(InternalValidationResult.reject("Attestation slot %s is not from target epoch %s", data.getSlot(), data.getTarget().getEpoch()));
    }
    // attestation.data.slot is within the last ATTESTATION_PROPAGATION_SLOT_RANGE slots (within a
    // MAXIMUM_GOSSIP_CLOCK_DISPARITY allowance) -- i.e. attestation.data.slot +
    // ATTESTATION_PROPAGATION_SLOT_RANGE >= current_slot >= attestation.data.slot (a client MAY
    // queue
    // future attestations for processing at the appropriate slot).
    final UInt64 currentTimeMillis = secondsToMillis(recentChainData.getStore().getTime());
    if (isCurrentTimeAfterAttestationPropagationSlotRange(currentTimeMillis, attestation) || isFromFarFuture(attestation, currentTimeMillis)) {
        return completedFuture(InternalValidationResult.IGNORE);
    }
    if (isCurrentTimeBeforeMinimumAttestationBroadcastTime(attestation, currentTimeMillis)) {
        return completedFuture(InternalValidationResult.SAVE_FOR_FUTURE);
    }
    // If it's not in the store, it may not have been processed yet so save for future.
    return recentChainData.retrieveBlockState(data.getBeacon_block_root()).thenCompose(maybeState -> maybeState.isEmpty() ? completedFuture(Optional.empty()) : resolveStateForAttestation(attestation, maybeState.get())).thenCompose(maybeState -> {
        if (maybeState.isEmpty()) {
            return completedFuture(InternalValidationResult.SAVE_FOR_FUTURE);
        }
        final BeaconState state = maybeState.get();
        // The committee index is within the expected range
        if (data.getIndex().isGreaterThanOrEqualTo(spec.getCommitteeCountPerSlot(state, data.getTarget().getEpoch()))) {
            return completedFuture(InternalValidationResult.reject("Committee index %s is out of range", data.getIndex()));
        }
        // subnet.
        if (receivedOnSubnetId.isPresent() && spec.computeSubnetForAttestation(state, attestation) != receivedOnSubnetId.getAsInt()) {
            return completedFuture(InternalValidationResult.reject("Attestation received on incorrect subnet (%s) for specified committee index (%s)", attestation.getData().getIndex(), receivedOnSubnetId.getAsInt()));
        }
        // The check below is not specified in the Eth2 networking spec, yet an attestation
        // with aggregation bits size greater/less than the committee size is invalid. So we
        // reject those attestations at the networking layer.
        final IntList committee = spec.getBeaconCommittee(state, data.getSlot(), data.getIndex());
        if (committee.size() != attestation.getAggregationBits().size()) {
            return completedFuture(InternalValidationResult.reject("Aggregation bit size %s is greater than committee size %s", attestation.getAggregationBits().size(), committee.size()));
        }
        return spec.isValidIndexedAttestation(state, validateableAttestation, signatureVerifier).thenApply(signatureResult -> {
            if (!signatureResult.isSuccessful()) {
                return InternalValidationResult.reject("Attestation is not a valid indexed attestation: %s", signatureResult.getInvalidReason());
            }
            // LMD vote
            if (!spec.getAncestor(recentChainData.getForkChoiceStrategy().orElseThrow(), data.getBeacon_block_root(), spec.computeStartSlotAtEpoch(data.getTarget().getEpoch())).map(ancestorOfLMDVote -> ancestorOfLMDVote.equals(data.getTarget().getRoot())).orElse(false)) {
                return InternalValidationResult.reject("Attestation LMD vote block does not descend from target block");
            }
            // The current finalized_checkpoint is an ancestor of the block defined by
            // aggregate.data.beacon_block_root
            // Because all nodes in the proto-array descend from the finalized block,
            // no further validation is needed to satisfy this rule.
            // Save committee shuffling seed since the state is available and
            // attestation is valid
            validateableAttestation.saveCommitteeShufflingSeed(state);
            return InternalValidationResult.ACCEPT;
        });
    });
}
Also used : ACCEPT(tech.pegasys.teku.statetransition.validation.ValidationResultCode.ACCEPT) AsyncBLSSignatureVerifier(tech.pegasys.teku.spec.logic.common.util.AsyncBLSSignatureVerifier) SafeFuture(tech.pegasys.teku.infrastructure.async.SafeFuture) SafeFuture.completedFuture(tech.pegasys.teku.infrastructure.async.SafeFuture.completedFuture) ONE(tech.pegasys.teku.infrastructure.unsigned.UInt64.ONE) OptionalInt(java.util.OptionalInt) ATTESTATION_PROPAGATION_SLOT_RANGE(tech.pegasys.teku.spec.config.Constants.ATTESTATION_PROPAGATION_SLOT_RANGE) IntList(it.unimi.dsi.fastutil.ints.IntList) AttestationData(tech.pegasys.teku.spec.datastructures.operations.AttestationData) RecentChainData(tech.pegasys.teku.storage.client.RecentChainData) ValidateableAttestation(tech.pegasys.teku.spec.datastructures.attestation.ValidateableAttestation) TimeUtilities.secondsToMillis(tech.pegasys.teku.infrastructure.time.TimeUtilities.secondsToMillis) Optional(java.util.Optional) UInt64(tech.pegasys.teku.infrastructure.unsigned.UInt64) Constants(tech.pegasys.teku.spec.config.Constants) ZERO(tech.pegasys.teku.infrastructure.unsigned.UInt64.ZERO) Spec(tech.pegasys.teku.spec.Spec) Bytes32(org.apache.tuweni.bytes.Bytes32) Checkpoint(tech.pegasys.teku.spec.datastructures.state.Checkpoint) Attestation(tech.pegasys.teku.spec.datastructures.operations.Attestation) BeaconState(tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconState) AttestationData(tech.pegasys.teku.spec.datastructures.operations.AttestationData) UInt64(tech.pegasys.teku.infrastructure.unsigned.UInt64) ValidateableAttestation(tech.pegasys.teku.spec.datastructures.attestation.ValidateableAttestation) Attestation(tech.pegasys.teku.spec.datastructures.operations.Attestation) BeaconState(tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconState) IntList(it.unimi.dsi.fastutil.ints.IntList)

Aggregations

IntList (it.unimi.dsi.fastutil.ints.IntList)1 Optional (java.util.Optional)1 OptionalInt (java.util.OptionalInt)1 Bytes32 (org.apache.tuweni.bytes.Bytes32)1 SafeFuture (tech.pegasys.teku.infrastructure.async.SafeFuture)1 SafeFuture.completedFuture (tech.pegasys.teku.infrastructure.async.SafeFuture.completedFuture)1 TimeUtilities.secondsToMillis (tech.pegasys.teku.infrastructure.time.TimeUtilities.secondsToMillis)1 UInt64 (tech.pegasys.teku.infrastructure.unsigned.UInt64)1 ONE (tech.pegasys.teku.infrastructure.unsigned.UInt64.ONE)1 ZERO (tech.pegasys.teku.infrastructure.unsigned.UInt64.ZERO)1 Spec (tech.pegasys.teku.spec.Spec)1 Constants (tech.pegasys.teku.spec.config.Constants)1 ATTESTATION_PROPAGATION_SLOT_RANGE (tech.pegasys.teku.spec.config.Constants.ATTESTATION_PROPAGATION_SLOT_RANGE)1 ValidateableAttestation (tech.pegasys.teku.spec.datastructures.attestation.ValidateableAttestation)1 Attestation (tech.pegasys.teku.spec.datastructures.operations.Attestation)1 AttestationData (tech.pegasys.teku.spec.datastructures.operations.AttestationData)1 Checkpoint (tech.pegasys.teku.spec.datastructures.state.Checkpoint)1 BeaconState (tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconState)1 AsyncBLSSignatureVerifier (tech.pegasys.teku.spec.logic.common.util.AsyncBLSSignatureVerifier)1 ACCEPT (tech.pegasys.teku.statetransition.validation.ValidationResultCode.ACCEPT)1