Skip to content

Commit

Permalink
cosmrs: support coins with amount 0, empty denom
Browse files Browse the repository at this point in the history
These can be used when the gas fee is zero, for example

Fixes #477
  • Loading branch information
tony-iqlusion committed Jul 31, 2024
1 parent c5db4e5 commit c175fa8
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 17 deletions.
59 changes: 43 additions & 16 deletions cosmrs/src/base/coin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,22 +23,12 @@ impl Coin {
}
}

impl TryFrom<proto::cosmos::base::v1beta1::Coin> for Coin {
type Error = ErrorReport;

fn try_from(proto: proto::cosmos::base::v1beta1::Coin) -> Result<Coin> {
Coin::try_from(&proto)
}
}

impl TryFrom<&proto::cosmos::base::v1beta1::Coin> for Coin {
type Error = ErrorReport;

fn try_from(proto: &proto::cosmos::base::v1beta1::Coin) -> Result<Coin> {
Ok(Coin {
denom: proto.denom.parse()?,
amount: proto.amount.parse()?,
})
impl Default for Coin {
fn default() -> Coin {
Coin {
denom: Denom::default(),
amount: 0
}
}
}

Expand All @@ -57,6 +47,32 @@ impl From<&Coin> for proto::cosmos::base::v1beta1::Coin {
}
}

impl TryFrom<proto::cosmos::base::v1beta1::Coin> for Coin {
type Error = ErrorReport;

fn try_from(proto: proto::cosmos::base::v1beta1::Coin) -> Result<Coin> {
Coin::try_from(&proto)
}
}

impl TryFrom<&proto::cosmos::base::v1beta1::Coin> for Coin {
type Error = ErrorReport;

fn try_from(proto: &proto::cosmos::base::v1beta1::Coin) -> Result<Coin> {
// Support an empty denom when the amount is `0`. See cosmos/cosmos-rust#477
if proto.denom.is_empty() && proto.amount == "0" {
Ok(Coin::default())
} else {
Ok(Coin {
denom: proto.denom.parse()?,
amount: proto.amount.parse()?,
})
}
}
}



impl fmt::Display for Coin {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
// See: https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/types/coin.go#L643-L645
Expand All @@ -66,10 +82,21 @@ impl fmt::Display for Coin {

#[cfg(test)]
mod tests {
use crate::proto;
use super::Coin;

#[test]
fn new() {
Coin::new(1000, "uatom").unwrap();
}

#[test]
fn zero_value_coin_with_empty_denom() {
let zero_proto = proto::cosmos::base::v1beta1::Coin::from(Coin::default());
assert_eq!(&zero_proto.denom, "");
assert_eq!(&zero_proto.amount, "0");

let zero_coin = Coin::try_from(zero_proto).unwrap();
assert_eq!(zero_coin, Coin::default())
}
}
2 changes: 1 addition & 1 deletion cosmrs/src/base/denom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use serde::{de, de::Error as _, ser, Deserialize, Serialize};
use std::{fmt, str::FromStr};

/// Denomination.
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Ord)]
pub struct Denom(String);

impl Denom {
Expand Down

0 comments on commit c175fa8

Please sign in to comment.