} fn from_decimal(decimal: &str) -> Result { let (height, offset) = decimal .split_once('.') .ok_or_else(|| anyhow!("missing period"))?; let height = Height(height.parse()?); let offset = offset.parse::()?; if offset >= height.subsidy() { bail!("invalid block offset"); } Ok(height.starting_sat() + offset) } fn from_percentile(percentile: &str) -> Result { if !percentile.ends_with('%') { bail!("invalid percentile: {}", percentile); } let percentile = percentile[..percentile.len() - 1].parse::()?; if percentile < 0.0 { bail!("invalid percentile: {}", percentile); } let last = Sat::LAST.n() as f64; let n = (percentile / 100.0 * last).round(); if n > last { bail!("invalid percentile: {}", percentile); } #[allow(clippy::cast_sign_loss, clippy::cast_possible_truncation)] Ok(Sat(n as u64)) } } impl PartialEq for Sat { fn eq(&self, other: &u64) -> bool { self.0 == *other