class ForkChoice {

  public SafeFuture<AttestationProcessingResult> onAttestation(
      final ValidateableAttestation attestation) {
    return recentChainData
        .retrieveCheckpointState(attestation.getData().getTarget())
        .thenCompose(
            targetBlockState ->
                onForkChoiceThread(
                    () -> {
                      final StoreTransaction transaction = recentChainData.startStoreTransaction();
                      final AttestationProcessingResult result =
                          on_attestation(
                              transaction, attestation, targetBlockState, getForkChoiceStrategy());
                      return result.isSuccessful()
                          ? transaction.commit().thenApply(__ -> result)
                          : SafeFuture.completedFuture(result);
                    }))
        .exceptionallyCompose(
            error -> {
              final Throwable rootCause = Throwables.getRootCause(error);
              if (rootCause instanceof InvalidCheckpointException) {
                return SafeFuture.completedFuture(
                    AttestationProcessingResult.invalid(rootCause.getMessage()));
              }
              return SafeFuture.failedFuture(error);
            });
  }

  public  ForkChoice(
      final ForkChoiceExecutor forkChoiceExecutor,
      final RecentChainData recentChainData,
      final StateTransition stateTransition);

}