text: from maize.consensus.constants import ConsensusConstants
  from maize.consensus.pos_quality import _expected_plot_size
  from maize.types.blockchain_format.sized_bytes import bytes32
  from maize.util.hash import std_hash
  from maize.util.ints import uint8, uint64, uint128
  
  
  def is_overflow_block(constants: ConsensusConstants, signage_point_index: uint8) -> bool:
      if signage_point_index >= constants.NUM_SPS_SUB_SLOT:
          raise ValueError("SP index too high")
      return signage_point_index >= constants.NUM_SPS_SUB_SLOT - constants.NUM_SP_INTERVALS_EXTRA
  
  
  def calculate_sp_interval_iters(constants: ConsensusConstants, sub_slot_iters: uint64) -> uint64:
      assert sub_slot_iters % constants.NUM_SPS_SUB_SLOT == 0
      return uint64(sub_slot_iters // constants.NUM_SPS_SUB_SLOT)
  
  
  def calculate_sp_iters(constants: ConsensusConstants, sub_slot_iters: uint64, signage_point_index: uint8) -> uint64:
      if signage_point_index >= constants.NUM_SPS_SUB_SLOT:
          raise ValueError("SP index too high")
      return uint64(calculate_sp_interval_iters(constants, sub_slot_iters) * signage_point_index)
  
  
  def calculate_ip_iters(
      constants: ConsensusConstants,
      sub_slot_iters: uint64,
      signage_point_index: uint8,
      required_iters: uint64,
  ) -> uint64:
      # Note that the SSI is for the block passed in, which might be in the previous epoch
      sp_iters = calculate_sp_iters(constants, sub_slot_iters, signage_point_index)
      sp_interval_iters: uint64 = calculate_sp_interval_iters(constants, sub_slot_iters)
      if sp_iters % sp_interval_iters != 0 or sp_iters >= sub_slot_iters:
          raise ValueError(f"Invalid sp iters {sp_iters} for this ssi {sub_slot_iters}")
  
      if required_iters >= sp_interval_iters or required_iters == 0:
          raise ValueError(
              f"Required iters {required_iters} is not below the sp interval iters {sp_interval_iters} "
              f"{sub_slot_iters} or not >0."
          )
  
      return uint64((sp_iters + constants.NUM_SP_INTERVALS_EXTRA * sp_interval_iters + required_iters) % sub_slot_iters)
  
  
  def calculate_iterations_quality(
      difficulty_constant_factor: uint128,
      quality_string: bytes32,
      size: int,
      difficulty: uint64,
      cc_sp_output_hash: bytes32,
  ) -> uint64:
      """
      Calculates the number of iterations from the quality. This is derives as the difficulty times the constant factor
      times a random number between 0 and 1 (based on quality string), divided by plot size.
      """
      sp_quality_string: bytes32 = std_hash(quality_string + cc_sp_output_hash)
  
      iters = uint64(
          int(difficulty)
          * int(difficulty_constant_factor)
          * int.from_bytes(sp_quality_string, "big", signed=False)
          // (int(pow(2, 256)) * int(_expected_plot_size(size)))
      )
      return max(iters, uint64(1))
  