Skip to Content
Scalus Club is now open! Join us to get an early access to new features 🎉
DocumentationLearningDesign PatternsValidity Range Normalization

Validity Range Normalization

Datatype for eliminating meaningless ranges, without the redundant inclusiveness flag (instead all range values are inclusive). Interval.never is represented as an improper interval.

The Problem

Plutus validity ranges can be represented in multiple equivalent ways:

  • Open ranges like (a, b) equal closed ranges like [a+1, b-1]
  • Infinite bounds are sometimes marked as closed despite representing unbounded time
  • The “always” range is inconsistently denoted as [-∞, +∞]

This forces validators to handle numerous case variations or risk incorrect behavior. The situation worsens for long-lived contracts since the standard method of communicating the range may change with any hard fork.

The Solution

Normalize all validity ranges into standardized forms:

  • ClosedRange(lower, upper) - Closed ranges with finite endpoints [a, b]
  • FromNegInf(upper) - Half-open range extending from negative infinity (-∞, x]
  • ToPosInf(lower) - Half-open range extending to positive infinity [x, +∞)
  • Always - Open range representing “always” (-∞, +∞)

This enables cleaner validator code with four straightforward cases instead of exhaustively matching numerous equivalent representations.

Implementation

The scalus-design-patterns package provides the NormalizedInterval type, helper functions and examples of use (Scaladoc format).

Note: Improper intervals (where lower bound > upper bound) return None from tryNormalize or throw an error from normalize.

Additional Resources

Last updated on