-
Notifications
You must be signed in to change notification settings - Fork 586
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
feat: add metadata for IBC tokens #3104
Conversation
Codecov Report
Additional details and impacted files@@ Coverage Diff @@
## main #3104 +/- ##
=======================================
Coverage ? 79.31%
=======================================
Files ? 188
Lines ? 13081
Branches ? 0
=======================================
Hits ? 10375
Misses ? 2271
Partials ? 435
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks a lot for this, @0xmuralik! This will be a great UX improvement!
I am wondering if we should have also a migration to add the metadata for the existing denom traces. We can fetch them using GetAllDenomTraces
. That way we would have metadata available already without the need for some tokens to be transferred. What do you think?
Sounds good. We can set MetaData in the initgenesis here after |
Yes, true, we should also do it in But wouldn't we also need a migration handler for chain upgrades? We could run this as an automatic migration handler by bumping the consensus version of transfer. |
|
||
if !m.keeper.bankKeeper.HasDenomMetaData(ctx, newTrace.IBCDenom()) { | ||
m.keeper.SetDenomMetaData(ctx, newTrace) | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This migration may have already been run and might not be run again. I think it is safer to make a separate migration only setting the denom metadata. Please let me know if you have any questions on how to do this. I'm also happy to receive that change in a followup pr, it would make reviews faster/easier
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have created a new migration and registered it with as version 3 migration. Feel free to take up the task if required.
Description: getMetaDataDescription(denomTrace), | ||
DenomUnits: []*banktypes.DenomUnit{ | ||
{ | ||
Denom: denomTrace.BaseDenom, | ||
Exponent: 0, | ||
}, | ||
}, | ||
// Setting base as IBChash Denom as SetDenomMetaData uses Base as storeKey | ||
// and the bank keeper will only have the IBCHash to get the denom metadata | ||
Base: denomTrace.IBCDenom(), | ||
Display: denomTrace.GetFullDenomPath(), | ||
Name: getMetaDataName(denomTrace), | ||
Symbol: getMetaDataSymbol(denomTrace), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we have an example print out of how this might look? Would be great if we could get product input on the desired formatting? cc @womensrights @adiraviraj @tmsdkeys
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For context, this pr would add metadata about IBC tokens into the state machine. This means when clients query a bank balance, instead of only seeing ibc/{hash}
they could also provide a flag to obtain back the metadata information stored here, such as the base denomination or the full history of this tokens hops (via channel/portIDs)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added a unit test for the new migration. The example metadata is available here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've known people asking for this on Discord, to have the metadata about IBC tokens as you would regular sdk tokens so think it's a good idea. Wrt the formatting, looks okay for me. The Base
field should normally equal DenomUnits.Denom
with Exponent
according to the bank module's metadata, but the reasoning is provided why it needs to deviate.
Rest looks okay for me. Maybe @womensrights has insights from user research?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is a great first step, but also adding in a human readable name to the current output would precisely cover what the metadata is used for. Front end developers are currently maintaining their own registries of assets to be displayed for their application. An example of such a registry is for Injective. Front ends need:
- token symbol, this is covered
- the location of the decimal place for the denom, I think this is covered from the exponent, from my understanding, e.g. the precision of ATOM is 6 dp, ATOM exponent is 6, uATOM is 0. In the example output given its not clear though as you have used an exponent of 0 for ubar and foo, foo should have exponent 6 assuming it is an sdk coin?
- human readable name, having the path is good, but then you would need to check which chain the token came from additionally to make this human readable
So I think this is already an improvement, just if there was also a way to add an additional human readable name somehow then this would be great but I'm not sure this is easily done. Also as a sidenote, I know there is a constraint on the metadata from the sdk types so this is not easy to change, but for the ibc denoms, you don't get any new information from looking at the Display
compared to Name
so in the long term I would question the need to have both
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the input, @womensrights!
- Regarding the exponent, if I am not mistaken I think at the moment it will be difficult to set it to the correct value, since this metadata is set on the receiving chain and the
FungibleTokenPacketData
does not contain that information at the moment. However, with channel upgradability it would be possible to extend the packet data and add extra information. - Regarding the lack of chain ID. Maybe the sending chain's chain ID could be added in the memo field? Not that I particularly want to continue adding more information in the memo file :), but maybe it's a solution for now. Your comment
if there was also a way to add an additional human readable name somehow
refers to adding the chain ID, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the exponent, as you linked the FungibleTokenPacketData
there isn't explicitly an exponent field but where does the logic to know the decimal place for the amount in the packet for a specific denom come from in this case?
The chainID would also not completely work as sometimes the chainID is not the same as what is considered the human branded name for the chain or you would need to remove the additional numbers. e.g. I think bandchain has chainID "laozi-mainnet" and the human readable name would be Bandchain
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the exponent, as you linked the FungibleTokenPacketData there isn't explicitly an exponent field but where does the logic to know the decimal place for the amount in the packet for a specific denom come from in this case?
The amount comes from the sdk Coin that is used in MsgTransfer
. Whatever that amount is, we put it in the FungibleTokenPacketData
, but we don't have any information about the exponent.
The chainID would also not completely work as sometimes the chainID is not the same as what is considered the human branded name for the chain or you would need to remove the additional numbers. e.g. I think bandchain has chainID "laozi-mainnet" and the human readable name would be Bandchain
True, good point! Then I guess we cannot do anything about this at the moment?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok I see, I guess this adr has not yet been implemented and right now its assumed that sdk coins all have 6 decimal places.
Yes I don't think there can be anything done about the chainIDs
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @0xmuralik! :)
@colin-axner @crodriguezvega If there are any additional changes required please let me know. Else fell free to take up this task in a different PR and close this one if necesssary. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM but see comments. More test assertions are needed and I'd recommend blending the added functionality into the existing SetDenomTrace
function to avoid accidental bugs in the future due to not calling both SetDenomTrace
and SetMetadata
@@ -277,6 +278,10 @@ func (k Keeper) OnRecvPacket(ctx sdk.Context, packet channeltypes.Packet, data t | |||
return errorsmod.Wrap(err, "failed to mint IBC tokens") | |||
} | |||
|
|||
if !k.bankKeeper.HasDenomMetaData(ctx, voucherDenom) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if we are running migrations such that all traces have metadata set, shouldn't we just make setting metadata a functionality of SetDenomTrace
? This avoids accidental incidents where the trace is set but the metadata isn't. There should never be an instance when you want to set the denom trace without setting the metadata as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess we could do that, although SetDenomTrace
is a setter function for a specific key in the store, so it would squeak to me a bit if we add SetDenomMetadata
there as well. Maybe we could have a helper function that wraps both SetDenomTrace
and SetDenomMetadata
. Happy to hear other people's thoughts.
var ( | ||
denom string | ||
totalEscrow sdk.Coin | ||
) | ||
if tc.recvIsSource { | ||
denom = sdk.DefaultBondDenom | ||
} else { | ||
denom = trace.IBCDenom() | ||
} | ||
totalEscrow = suite.chainB.GetSimApp().TransferKeeper.GetTotalEscrowForDenom(suite.chainB.GetContext(), denom) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I realised that this could be simplified. It was actually testing the wrong thing, I think, but looks like by chance the tests passed...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thank you @0xmuralik and @crodriguezvega!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! Looks good to me, left some suggestions which were only nits
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM thanks @0xmuralik, just left a few small comments but it looks great 👍
Thanks for the reviews, @colin-axner, @damiannolan and @chatton. I addressed all the comments and the PR is then ready for merge after CI passes. |
Description
Fixes: #14181
See: cosmos/cosmos-sdk#14894
Commit Message / Changelog Entry
see the guidelines for commit messages. (view raw markdown for examples)
Before we can merge this PR, please make sure that all the following items have been
checked off. If any of the checklist items are not applicable, please leave them but
write a little note why.
docs/
) or specification (x/<module>/spec/
).godoc
comments.Files changed
in the Github PR explorer.Codecov Report
in the comment section below once CI passes.