public void maybeUpdateLowestSequenceAndEpoch(int incomingSequence, short incomingEpoch) {
        if (incomingEpoch == epoch && incomingSequence < this.lowestSequence)
            this.lowestSequence = incomingSequence;
        if (incomingEpoch > this.epoch) {
            this.epoch = incomingEpoch;
            this.lowestSequence = incomingSequence;
        }
    }
An OutOfOrderSequence loop can happen for any idempotent/transactional producer when a lower sequence fails with
a retriable error and a higher sequence is successfully written. The lower sequence will fail with
OutOfOrderSequence and retry until retries run out.

Here, we keep the lowest sequence seen in order to prevent an OutOfOrderSequence loop when verifying. This does
not solve the error loop for idempotent producers or transactional producers that fail before verification
starts. When verification fails with a retriable error (ie. NOT_COORDINATOR), the VerificationStateEntry
maintains the lowest sequence number it sees and blocks higher sequences from being written to the log. However,
if we encounter a new and lower sequence when verifying, we want to block sequences higher than that new
sequence. Additionally, if the epoch is bumped, the sequence is reset and any previous sequence must be disregarded.

Thus, we update the lowest sequence if there is a batch needing verification that has:
a) a lower sequence for the same epoch
b) a higher epoch -- update the epoch here too
storage/src/main/java/org/apache/kafka/storage/internals/log/VerificationStateEntry.java