Search in sources :

Example 1 with AsyncBLSSignatureVerifier

use of tech.pegasys.teku.spec.logic.common.util.AsyncBLSSignatureVerifier 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)

Example 2 with AsyncBLSSignatureVerifier

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

the class AttestationValidatorTest method shouldRejectAttestationsThatHaveLMDVotesInconsistentWithTargetRoot.

@Test
public void shouldRejectAttestationsThatHaveLMDVotesInconsistentWithTargetRoot() {
    final StateAndBlockSummary blockAndState = storageSystem.getChainHead();
    final Attestation attestation = attestationGenerator.validAttestation(blockAndState);
    final AsyncBLSSignatureVerifier signatureVerifier = mock(AsyncBLSSignatureVerifier.class);
    final AttestationValidator validator = new AttestationValidator(spec, recentChainData, signatureVerifier);
    final AttestationData data = attestation.getData();
    final Checkpoint checkpoint = new Checkpoint(data.getTarget().getEpoch().minusMinZero(1), blockAndState.getBeaconBlock().orElseThrow().getParentRoot());
    final int expectedSubnetId = spec.computeSubnetForAttestation(blockAndState.getState(), attestation);
    // the signature would be invalid, but it's actually not the point of the test case.
    when(signatureVerifier.verify(anyList(), any(Bytes.class), any())).thenReturn(SafeFuture.completedFuture(true));
    assertThat(validator.validate(ValidateableAttestation.fromNetwork(spec, attestationSchema.create(attestation.getAggregationBits(), new AttestationData(data.getSlot(), data.getIndex(), data.getBeacon_block_root(), data.getSource(), checkpoint), attestation.getAggregateSignature()), expectedSubnetId))).matches(rejected("descend from target block"), "Rejected does not descend from target block");
}
Also used : AttestationData(tech.pegasys.teku.spec.datastructures.operations.AttestationData) Bytes(org.apache.tuweni.bytes.Bytes) StateAndBlockSummary(tech.pegasys.teku.spec.datastructures.blocks.StateAndBlockSummary) Checkpoint(tech.pegasys.teku.spec.datastructures.state.Checkpoint) AsyncBLSSignatureVerifier(tech.pegasys.teku.spec.logic.common.util.AsyncBLSSignatureVerifier) Attestation(tech.pegasys.teku.spec.datastructures.operations.Attestation) ValidateableAttestation(tech.pegasys.teku.spec.datastructures.attestation.ValidateableAttestation) Checkpoint(tech.pegasys.teku.spec.datastructures.state.Checkpoint) Test(org.junit.jupiter.api.Test)

Aggregations

ValidateableAttestation (tech.pegasys.teku.spec.datastructures.attestation.ValidateableAttestation)2 Attestation (tech.pegasys.teku.spec.datastructures.operations.Attestation)2 AttestationData (tech.pegasys.teku.spec.datastructures.operations.AttestationData)2 Checkpoint (tech.pegasys.teku.spec.datastructures.state.Checkpoint)2 AsyncBLSSignatureVerifier (tech.pegasys.teku.spec.logic.common.util.AsyncBLSSignatureVerifier)2 IntList (it.unimi.dsi.fastutil.ints.IntList)1 Optional (java.util.Optional)1 OptionalInt (java.util.OptionalInt)1 Bytes (org.apache.tuweni.bytes.Bytes)1 Bytes32 (org.apache.tuweni.bytes.Bytes32)1 Test (org.junit.jupiter.api.Test)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