-
Notifications
You must be signed in to change notification settings - Fork 344
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature request: a cosmwasm_std::Coins
class similar to sdk.Coins
#1377
Comments
on a separate note, it may also be interesting to have a struct DecCoin {
pub denom: String,
pub amount: Decimal,
} |
This also came up recently in #1359. The main issue I have with this is that Coins is a list, which It would be good to implement Coins in a type that makes dirty instances impossible, like a map from denom to uint. Sorting can happen whenever you roll out the values. |
in our similarly, we can also do sorting every time but the map idea makes sense as well, and is perhaps cheaper in gas. i'm wondering if Rust has something similar to Python's |
Looks good, but it can be implemented easier with fn add(&mut self, rhs: Coin) {
*self.0.entry(rhs.denom).or_default() += rhs.amount;
} The purging only needs to be done when constructing the instance (where you loop through inputs anyways) and in deduct you only need to worry about the denom you are deducting. |
Yeah, i'm also thinking about using a BTreeMap which is naturally sorted by denom. It's more expensive compared to HashMap when doing searches or insertions, but the difference should be acceptable since contracts usually only deal with small numbers of coins. I'm going to create a separate repo to play with the idea before contributing here. |
Yeah I think BTreeMap makes sense. Happy to see and review a draft PR! |
Having an |
hi @webmaster128, i have been playing with the BTreeMap implementation of Coins, and certainly it has many good properties. however, there are two issues related serialization, which i want to learn about your thoughts. my #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
pub struct Coins(pub BTreeMap<String, Uint128>); 1. serialization into JSONwhile Rust vector types serializes to JSON arrays, e.g. // typescript definition of Vec<cosmwasm_std::Coin>
type VecCoin = {
denom: string;
amount: string;
}[]; map types such as BTreeMap serialize to JSON objects: // typescript for BTreeMap<String, Uint128>
type BtreemapStringUint128 = {
[key: string]: string;
}; i'm not sure if this is desired. on the one hand, it is a more compact representation (shorter JSON strings, so cheaper gas when writing to contract store?) on the other hand, it 1) losses the ordering of keys, 2) may cause confusions for developers. i can certainly manually implement the 2. if the string has a duplicate key, deserialization will NOT throw an errorif i attempt to deserialize the following JSON string: let s = r#"{
"uatom": "12345",
"factory/osmo1234abcd/subdenom": "88888",
"uatom": "67890",
"ibc/1234ABCD": "69420"
}"#;
let coins = serde_json::from_str::<Coins>(s).unwrap(); // success, no error the JSON string contains a duplicate denom turns out JSON's syntax does allow duplicate keys... i did not know this. the same when casting from let vec = vec![
coin(12345, "uatom"),
coin(88888, "factory/osmo1234abcd/subdenom"),
coin(67890, "uatom"),
coin(69420, "ibc/1234ABCD"),
];
let coins = vec
.into_iter()
.map(|coin| (coin.denom, coin.amount))
.collect::<Coins>(); the result is the same as in the JSON example: no error, the i think this can be solved by:
thoughts? |
UPDATE: i implemented the custom it still uses the |
I think serialising this format doesn't make sense. It should only be used as an in-memory helper. I would have simple And just convert in memory when needed, and convert back to a Vec for serialization. If you want to avoid that (coding) overhead, I would implement the serialize and deserialise as simple wrappers: Basically, deserialise into |
Hey, @larry0x! Are you still willing to go for this, or are you dropping it? |
@uint I created a proof-of-concept with serialization/deserialization (but without the arithmetic methods, yet) here: https://github.com/steak-enjoyers/cw-plus-plus/tree/main/packages/coins I think this can remain as a 3rd party helper library instead of part of |
Thanks, cool! @ethanfrey Is this something we want to happen in |
I am very happy with this as a 3rd party module. |
I'm very supportive of a Coins object that wraps At least getting the version thats recommended for doing arithmetic on |
I agree with @ValarDragon (despite my general tendency to minimalism). This is also a low hanging fruit for us to develop and maintain. I'd love to start the work based on @larry0x's code. Unfortunately I cannot do that due to licensing. Would you submit that file under Apache 2.0, Larry? Feel free to just add it as part of a draft PR and I can pick it up. |
I can make a draft PR, but a problem is that pub struct Coins(BTreeMap<String, Uint128>); but |
Yes, we don't use serde for |
@webmaster128 draft PR ---> #1487 |
protocols often need to handle multiple coins at the same time. for SDK modules, this is easy to do thanks to the
sdk.Coins
class, which provides a number of useful helper methods. however i am not aware of something similar incosmwasm_std
.i propose to create a
cosmwasm_std::Coins
class with methods that mirror those ofsdk.Coins
:i have worked on the
cw_asset
library, which provides a similar:AssetList
class: https://github.com/mars-protocol/cw-asset/blob/main/src/asset_list.rsthis new class can be added without breaking the existing API.
it would be great if the funds field in MessageInfo is also changed to Coins instead Coin, but then it would be API-breaking.
The text was updated successfully, but these errors were encountered: