@Test public void validateLatestFinalizedCheckpoint_withWSCheckpoint_shouldRunChecksWhenFinalizedAfterCheckpoint_shouldFail() { final Checkpoint wsCheckpoint = new Checkpoint(UInt64.valueOf(100), Bytes32.fromHexStringLenient("0x01")); final WeakSubjectivityConfig config = WeakSubjectivityConfig.builder().weakSubjectivityCheckpoint(wsCheckpoint).build(); final WeakSubjectivityValidator validator = new WeakSubjectivityValidator(config, calculator, policies); final int validatorCount = 101; when(checkpointState.getEpoch()).thenReturn(wsCheckpoint.getEpoch().plus(1)); when(calculator.isWithinWeakSubjectivityPeriod(checkpointState, currentSlot)).thenReturn(false); when(calculator.getActiveValidators(checkpointState.getState())).thenReturn(validatorCount); validator.validateLatestFinalizedCheckpoint(checkpointState, currentSlot); orderedPolicyMocks .verify(policies.get(0)) .onFinalizedCheckpointOutsideOfWeakSubjectivityPeriod( checkpointState, validatorCount, currentSlot); orderedPolicyMocks .verify(policies.get(1)) .onFinalizedCheckpointOutsideOfWeakSubjectivityPeriod( checkpointState, validatorCount, currentSlot); orderedPolicyMocks.verifyNoMoreInteractions(); }
public void validateLatestFinalizedCheckpoint( final CheckpointState latestFinalizedCheckpoint, final UInt64 currentSlot) { if (isPriorToWSCheckpoint(latestFinalizedCheckpoint)) { LOG.debug( "Latest finalized checkpoint at epoch {} is prior to weak subjectivity checkpoint at epoch {}. Defer validation.", latestFinalizedCheckpoint.getEpoch(), config.getWeakSubjectivityCheckpoint().orElseThrow().getEpoch()); return; } if (isAtWSCheckpoint(latestFinalizedCheckpoint) && !isWSCheckpointRoot(latestFinalizedCheckpoint.getRoot())) { handleInconsistentWsCheckpoint(latestFinalizedCheckpoint.getBlock()); } UInt64 currentEpoch = compute_epoch_at_slot(currentSlot); final Optional<UInt64> suppressionEpoch = getSuppressWSPeriodChecksUntilEpoch(currentSlot); final boolean shouldSuppressErrors = suppressionEpoch.map(e -> e.isGreaterThan(currentEpoch)).orElse(false); final boolean withinWSPeriod = isWithinWSPeriod(latestFinalizedCheckpoint, currentSlot); if (!withinWSPeriod && !shouldSuppressErrors) { handleFinalizedCheckpointOutsideWSPeriod(latestFinalizedCheckpoint, currentSlot); } else if (!withinWSPeriod && currentSlot.mod(SUPPRESSION_WARNING_PERIOD_IN_SLOTS).equals(UInt64.ZERO) && getAndSetLastLoggedSlot(currentSlot).isLessThan(currentSlot)) { STATUS_LOG.warnWeakSubjectivityChecksSuppressed(suppressionEpoch.orElseThrow()); } }
WeakSubjectivityValidator { public void validateLatestFinalizedCheckpoint( final CheckpointState latestFinalizedCheckpoint, final UInt64 currentSlot) { if (isPriorToWSCheckpoint(latestFinalizedCheckpoint)) { LOG.debug( "Latest finalized checkpoint at epoch {} is prior to weak subjectivity checkpoint at epoch {}. Defer validation.", latestFinalizedCheckpoint.getEpoch(), config.getWeakSubjectivityCheckpoint().orElseThrow().getEpoch()); return; } if (isAtWSCheckpoint(latestFinalizedCheckpoint) && !isWSCheckpointRoot(latestFinalizedCheckpoint.getRoot())) { handleInconsistentWsCheckpoint(latestFinalizedCheckpoint.getBlock()); } UInt64 currentEpoch = compute_epoch_at_slot(currentSlot); final Optional<UInt64> suppressionEpoch = getSuppressWSPeriodChecksUntilEpoch(currentSlot); final boolean shouldSuppressErrors = suppressionEpoch.map(e -> e.isGreaterThan(currentEpoch)).orElse(false); final boolean withinWSPeriod = isWithinWSPeriod(latestFinalizedCheckpoint, currentSlot); if (!withinWSPeriod && !shouldSuppressErrors) { handleFinalizedCheckpointOutsideWSPeriod(latestFinalizedCheckpoint, currentSlot); } else if (!withinWSPeriod && currentSlot.mod(SUPPRESSION_WARNING_PERIOD_IN_SLOTS).equals(UInt64.ZERO) && getAndSetLastLoggedSlot(currentSlot).isLessThan(currentSlot)) { STATUS_LOG.warnWeakSubjectivityChecksSuppressed(suppressionEpoch.orElseThrow()); } } }
WeakSubjectivityValidator { public void validateLatestFinalizedCheckpoint( final CheckpointState latestFinalizedCheckpoint, final UInt64 currentSlot) { if (isPriorToWSCheckpoint(latestFinalizedCheckpoint)) { LOG.debug( "Latest finalized checkpoint at epoch {} is prior to weak subjectivity checkpoint at epoch {}. Defer validation.", latestFinalizedCheckpoint.getEpoch(), config.getWeakSubjectivityCheckpoint().orElseThrow().getEpoch()); return; } if (isAtWSCheckpoint(latestFinalizedCheckpoint) && !isWSCheckpointRoot(latestFinalizedCheckpoint.getRoot())) { handleInconsistentWsCheckpoint(latestFinalizedCheckpoint.getBlock()); } UInt64 currentEpoch = compute_epoch_at_slot(currentSlot); final Optional<UInt64> suppressionEpoch = getSuppressWSPeriodChecksUntilEpoch(currentSlot); final boolean shouldSuppressErrors = suppressionEpoch.map(e -> e.isGreaterThan(currentEpoch)).orElse(false); final boolean withinWSPeriod = isWithinWSPeriod(latestFinalizedCheckpoint, currentSlot); if (!withinWSPeriod && !shouldSuppressErrors) { handleFinalizedCheckpointOutsideWSPeriod(latestFinalizedCheckpoint, currentSlot); } else if (!withinWSPeriod && currentSlot.mod(SUPPRESSION_WARNING_PERIOD_IN_SLOTS).equals(UInt64.ZERO) && getAndSetLastLoggedSlot(currentSlot).isLessThan(currentSlot)) { STATUS_LOG.warnWeakSubjectivityChecksSuppressed(suppressionEpoch.orElseThrow()); } } WeakSubjectivityValidator(
      final WeakSubjectivityConfig config,
      WeakSubjectivityCalculator calculator,
      List<WeakSubjectivityViolationPolicy> violationPolicies); }
WeakSubjectivityValidator { public void validateLatestFinalizedCheckpoint( final CheckpointState latestFinalizedCheckpoint, final UInt64 currentSlot) { if (isPriorToWSCheckpoint(latestFinalizedCheckpoint)) { LOG.debug( "Latest finalized checkpoint at epoch {} is prior to weak subjectivity checkpoint at epoch {}. Defer validation.", latestFinalizedCheckpoint.getEpoch(), config.getWeakSubjectivityCheckpoint().orElseThrow().getEpoch()); return; } if (isAtWSCheckpoint(latestFinalizedCheckpoint) && !isWSCheckpointRoot(latestFinalizedCheckpoint.getRoot())) { handleInconsistentWsCheckpoint(latestFinalizedCheckpoint.getBlock()); } UInt64 currentEpoch = compute_epoch_at_slot(currentSlot); final Optional<UInt64> suppressionEpoch = getSuppressWSPeriodChecksUntilEpoch(currentSlot); final boolean shouldSuppressErrors = suppressionEpoch.map(e -> e.isGreaterThan(currentEpoch)).orElse(false); final boolean withinWSPeriod = isWithinWSPeriod(latestFinalizedCheckpoint, currentSlot); if (!withinWSPeriod && !shouldSuppressErrors) { handleFinalizedCheckpointOutsideWSPeriod(latestFinalizedCheckpoint, currentSlot); } else if (!withinWSPeriod && currentSlot.mod(SUPPRESSION_WARNING_PERIOD_IN_SLOTS).equals(UInt64.ZERO) && getAndSetLastLoggedSlot(currentSlot).isLessThan(currentSlot)) { STATUS_LOG.warnWeakSubjectivityChecksSuppressed(suppressionEpoch.orElseThrow()); } } WeakSubjectivityValidator(
      final WeakSubjectivityConfig config,
      WeakSubjectivityCalculator calculator,
      List<WeakSubjectivityViolationPolicy> violationPolicies); static WeakSubjectivityValidator strict(final WeakSubjectivityConfig config); static WeakSubjectivityValidator lenient(); static WeakSubjectivityValidator lenient(final WeakSubjectivityConfig config); Optional<Checkpoint> getWSCheckpoint(); SafeFuture<Void> validateChainIsConsistentWithWSCheckpoint(
      CombinedChainDataClient chainData); void validateLatestFinalizedCheckpoint(
      final CheckpointState latestFinalizedCheckpoint, final UInt64 currentSlot); boolean isBlockValid(
      final SignedBeaconBlock block, ForkChoiceStrategy forkChoiceStrategy); void handleValidationFailure(final String message); void handleValidationFailure(final String message, Throwable error); @Override boolean equals(final Object o); @Override int hashCode(); }
WeakSubjectivityValidator { public void validateLatestFinalizedCheckpoint( final CheckpointState latestFinalizedCheckpoint, final UInt64 currentSlot) { if (isPriorToWSCheckpoint(latestFinalizedCheckpoint)) { LOG.debug( "Latest finalized checkpoint at epoch {} is prior to weak subjectivity checkpoint at epoch {}. Defer validation.", latestFinalizedCheckpoint.getEpoch(), config.getWeakSubjectivityCheckpoint().orElseThrow().getEpoch()); return; } if (isAtWSCheckpoint(latestFinalizedCheckpoint) && !isWSCheckpointRoot(latestFinalizedCheckpoint.getRoot())) { handleInconsistentWsCheckpoint(latestFinalizedCheckpoint.getBlock()); } UInt64 currentEpoch = compute_epoch_at_slot(currentSlot); final Optional<UInt64> suppressionEpoch = getSuppressWSPeriodChecksUntilEpoch(currentSlot); final boolean shouldSuppressErrors = suppressionEpoch.map(e -> e.isGreaterThan(currentEpoch)).orElse(false); final boolean withinWSPeriod = isWithinWSPeriod(latestFinalizedCheckpoint, currentSlot); if (!withinWSPeriod && !shouldSuppressErrors) { handleFinalizedCheckpointOutsideWSPeriod(latestFinalizedCheckpoint, currentSlot); } else if (!withinWSPeriod && currentSlot.mod(SUPPRESSION_WARNING_PERIOD_IN_SLOTS).equals(UInt64.ZERO) && getAndSetLastLoggedSlot(currentSlot).isLessThan(currentSlot)) { STATUS_LOG.warnWeakSubjectivityChecksSuppressed(suppressionEpoch.orElseThrow()); } } WeakSubjectivityValidator(
      final WeakSubjectivityConfig config,
      WeakSubjectivityCalculator calculator,
      List<WeakSubjectivityViolationPolicy> violationPolicies); static WeakSubjectivityValidator strict(final WeakSubjectivityConfig config); static WeakSubjectivityValidator lenient(); static WeakSubjectivityValidator lenient(final WeakSubjectivityConfig config); Optional<Checkpoint> getWSCheckpoint(); SafeFuture<Void> validateChainIsConsistentWithWSCheckpoint(
      CombinedChainDataClient chainData); void validateLatestFinalizedCheckpoint(
      final CheckpointState latestFinalizedCheckpoint, final UInt64 currentSlot); boolean isBlockValid(
      final SignedBeaconBlock block, ForkChoiceStrategy forkChoiceStrategy); void handleValidationFailure(final String message); void handleValidationFailure(final String message, Throwable error); @Override boolean equals(final Object o); @Override int hashCode();  }