class BlocksByRangeListenerWrapper implements ResponseStreamListener<SignedBeaconBlock> {

  @Override
  public SafeFuture<?> onResponse(SignedBeaconBlock response) {
    return SafeFuture.of(
        () -> {
          UInt64 blockSlot = response.getSlot();
          if (!blockSlotIsInRange(blockSlot)) {
            throw new BlocksByRangeResponseInvalidResponseException(peer, BLOCK_SLOT_NOT_IN_RANGE);
          }

          if (!blockSlotMatchesTheStep(blockSlot)) {
            throw new BlocksByRangeResponseInvalidResponseException(
                peer, BLOCK_SLOT_DOES_NOT_MATCH_STEP);
          }

          if (!blockSlotGreaterThanPreviousBlockSlot(blockSlot)) {
            throw new BlocksByRangeResponseInvalidResponseException(
                peer, BLOCK_SLOT_NOT_GREATER_THAN_PREVIOUS_BLOCK_SLOT);
          }

          if (!blockParentRootMatches(response.getParent_root())) {
            throw new BlocksByRangeResponseInvalidResponseException(
                peer, BLOCK_PARENT_ROOT_DOES_NOT_MATCH);
          }

          maybeSlotOfLastBlock = Optional.of(blockSlot);
          maybeRootOfLastBlock = Optional.of(response.getRoot());
          return blockResponseListener.onResponse(response);
        });
  }

  public  BlocksByRangeListenerWrapper(
      Peer peer,
      ResponseStreamListener<SignedBeaconBlock> blockResponseListener,
      UInt64 startSlot,
      UInt64 count,
      UInt64 step);

}