diff --git a/src/index.rs b/src/index.rs index ae3483d996..71a8da1b2d 100644 --- a/src/index.rs +++ b/src/index.rs @@ -525,7 +525,7 @@ impl Index { .pop_front() .ok_or_else(|| anyhow!("insufficient inputs for transaction outputs"))?; - if Ordinal(range.0).rarity() > Rarity::Common { + if !Ordinal(range.0).is_common() { ordinal_to_satpoint.insert( &range.0, &encode_satpoint(SatPoint { diff --git a/src/ordinal.rs b/src/ordinal.rs index fd88e720d1..a97548c0bd 100644 --- a/src/ordinal.rs +++ b/src/ordinal.rs @@ -52,6 +52,14 @@ impl Ordinal { self.into() } + /// `Ordinal::rarity` is expensive and is called frequently when indexing. + /// Ordinal::is_common only checks if self is `Rarity::Common` but is + /// much faster. + pub(crate) fn is_common(self) -> bool { + let epoch = self.epoch(); + (self.0 - epoch.starting_ordinal().0) % epoch.subsidy() != 0 + } + pub(crate) fn name(self) -> String { let mut x = Self::SUPPLY - self.0; let mut name = String::new(); @@ -597,4 +605,23 @@ mod tests { case(Ordinal::LAST.n() / (n + 1)); } } + + #[test] + fn is_common() { + fn case(n: u64) { + assert_eq!( + Ordinal(n).is_common(), + Ordinal(n).rarity() == Rarity::Common + ); + } + + case(0); + case(1); + case(50 * COIN_VALUE - 1); + case(50 * COIN_VALUE); + case(50 * COIN_VALUE + 1); + case(2067187500000000 - 1); + case(2067187500000000); + case(2067187500000000 + 1); + } }