class SlotProcessor {

  public void onTick(final UInt64 currentTime) {
    final UInt64 genesisTime = recentChainData.getGenesisTime();
    if (currentTime.compareTo(genesisTime) < 0) {
      return;
    }
    if (isNextSlotDue(currentTime, genesisTime) && syncService.isSyncActive()) {
      processSlotWhileSyncing();
      nodeSlot.inc();
      return;
    }

    final UInt64 calculatedSlot = ForkChoiceUtil.getCurrentSlot(currentTime, genesisTime);
    // tolerate 1 slot difference, not more
    if (calculatedSlot.compareTo(nodeSlot.getValue().plus(ONE)) > 0) {
      eventLog.nodeSlotsMissed(nodeSlot.getValue(), calculatedSlot);
      nodeSlot.setValue(calculatedSlot);
    }

    final UInt64 epoch = compute_epoch_at_slot(nodeSlot.getValue());
    final UInt64 nodeSlotStartTime =
        ForkChoiceUtil.getSlotStartTime(nodeSlot.getValue(), genesisTime);
    if (isSlotStartDue(calculatedSlot)) {
      processSlotStart(epoch);
    }
    if (isSlotAttestationDue(calculatedSlot, currentTime, nodeSlotStartTime)) {
      processSlotAttestation(epoch);
    }
    if (isSlotAggregationDue(calculatedSlot, currentTime, nodeSlotStartTime)) {
      processSlotAggregate();
      nodeSlot.inc();
    }
  }

  @VisibleForTesting  SlotProcessor(
      final RecentChainData recentChainData,
      final SyncService syncService,
      final ForkChoice forkChoice,
      final Eth2Network p2pNetwork,
      final SlotEventsChannel slotEventsChannelPublisher,
      final EventBus eventBus,
      final EventLogger eventLogger);
  public  SlotProcessor(
      final RecentChainData recentChainData,
      final SyncService syncService,
      final ForkChoice forkChoice,
      final Eth2Network p2pNetwork,
      final SlotEventsChannel slotEventsChannelPublisher,
      final EventBus eventBus);

}