Skip to content

Commit

Permalink
cosmrs: match upstream Cosmos SDK's Denom validation logic (cosmos#470)
Browse files Browse the repository at this point in the history
Implements the same checks as the upstream Cosmos SDK's `MatchDenom`:

https://github.com/cosmos/cosmos-sdk/blob/6a07568/types/coin.go#L885-L906
  • Loading branch information
tony-iqlusion authored May 31, 2024
1 parent d8ca2aa commit ced74a7
Showing 1 changed file with 27 additions and 7 deletions.
34 changes: 27 additions & 7 deletions cosmrs/src/base/denom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@ use std::{fmt, str::FromStr};
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
pub struct Denom(String);

impl Denom {
/// Minimum length of a [`Denom`].
pub const MIN_LENGTH: usize = 3;

/// Maximum length of a [`Denom`].
pub const MAX_LENGTH: usize = 128;
}

impl AsRef<str> for Denom {
fn as_ref(&self) -> &str {
self.0.as_ref()
Expand All @@ -21,15 +29,18 @@ impl fmt::Display for Denom {
impl FromStr for Denom {
type Err = ErrorReport;

/// NOTE: implements the same checks as the `MatchDenom` function from the upstream Cosmos SDK.
/// <https://github.com/cosmos/cosmos-sdk/blob/6a07568/types/coin.go#L885-L906>
fn from_str(s: &str) -> Result<Self> {
// TODO(tarcieri): ensure this is the proper validation for a denom name
if s.chars()
.all(|c| matches!(c, 'A'..='Z' | 'a'..='z' | '0'..='9' | '/' | ':' | '.' | '_' | '-'))
{
Ok(Denom(s.to_owned()))
} else {
Err(Error::Denom { name: s.to_owned() }.into())
if s.len() < Self::MIN_LENGTH || s.len() > Self::MAX_LENGTH {
return Err(Error::Denom { name: s.to_owned() }.into());
}

if !s.chars().all(is_valid_denom_char) {
return Err(Error::Denom { name: s.to_owned() }.into());
}

Ok(Denom(s.to_owned()))
}
}

Expand All @@ -47,6 +58,15 @@ impl Serialize for Denom {
}
}

/// Check if a given character is allowed in a `Denom` name.
///
/// NOTE: implements the same checks as the `isValidRune` function from the upstream Cosmos SDK.
/// <https://github.com/cosmos/cosmos-sdk/blob/6a07568/types/coin.go#L879-L883>
#[inline]
fn is_valid_denom_char(c: char) -> bool {
matches!(c, 'A'..='Z' | 'a'..='z' | '0'..='9' | '/' | ':' | '.' | '_' | '-')
}

#[cfg(test)]
mod tests {
use super::Denom;
Expand Down

0 comments on commit ced74a7

Please sign in to comment.