class WeakSubjectivityValidator {

  public SafeFuture<Void> validateChainIsConsistentWithWSCheckpoint(
      CombinedChainDataClient chainData) {
    if (config.getWeakSubjectivityCheckpoint().isEmpty()) {
      // Nothing to validate against
      return SafeFuture.COMPLETE;
    }
    final Checkpoint wsCheckpoint = config.getWeakSubjectivityCheckpoint().get();
    if (!chainData.isFinalizedEpoch(wsCheckpoint.getEpoch())) {
      // Checkpoint is in the future - nothing to validate yet
      return SafeFuture.COMPLETE;
    }

    return chainData
        .getBlockInEffectAtSlot(wsCheckpoint.getEpochStartSlot())
        .thenAccept(
            maybeBlock -> {
              // We must have a block at this slot because we know this epoch is finalized
              SignedBeaconBlock blockAtCheckpointSlot = maybeBlock.orElseThrow();
              if (!blockAtCheckpointSlot.getRoot().equals(wsCheckpoint.getRoot())) {
                handleInconsistentWsCheckpoint(blockAtCheckpointSlot);
              }
            });
  }

    WeakSubjectivityValidator(
      final WeakSubjectivityConfig config,
      WeakSubjectivityCalculator calculator,
      List<WeakSubjectivityViolationPolicy> violationPolicies);

}