def METHOD_NAME(self, state, initial_dt):
    """Perform a full ODE solver step.
    This includes the acceptance/rejection decision as governed by error estimation
    and steprule.
    """
    dt = initial_dt
    step_is_sufficiently_small = False
    proposed_state = None
    while not step_is_sufficiently_small:
        proposed_state = self.attempt_step(state, dt)
        # Acceptance/Rejection due to the step-rule
        internal_norm = self.steprule.errorest_to_norm(
            errorest=proposed_state.error_estimate,
            reference_state=proposed_state.reference_state,
        )
        step_is_sufficiently_small = self.steprule.is_accepted(internal_norm)
        suggested_dt = self.steprule.suggest(
            dt, internal_norm, localconvrate=self.order + 1
        )
        # Get a new step-size for the next step
        if step_is_sufficiently_small:
            dt = min(suggested_dt, state.ivp.tmax - proposed_state.t)
        else:
            dt = min(suggested_dt, state.ivp.tmax - state.t)
    self.method_callback(state)
    return proposed_state, dt