Skip to content
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

Merged
merged 43 commits into from
Sep 12, 2023

Conversation

0xmuralik
Copy link
Contributor

Description

Fixes: #14181

See: cosmos/cosmos-sdk#14894

Commit Message / Changelog Entry

type: commit message

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.

  • Targeted PR against correct branch (see CONTRIBUTING.md).
  • Linked to Github issue with discussion and accepted design OR link to spec that describes this work.
  • Code follows the module structure standards and Go style guide.
  • Wrote unit and integration tests.
  • Updated relevant documentation (docs/) or specification (x/<module>/spec/).
  • Added relevant godoc comments.
  • Provide a commit message to be used for the changelog entry in the PR description for review.
  • Re-reviewed Files changed in the Github PR explorer.
  • Review Codecov Report in the comment section below once CI passes.

@codecov-commenter
Copy link

codecov-commenter commented Feb 3, 2023

Codecov Report

❗ No coverage uploaded for pull request base (main@b53bfa5). Click here to learn what that means.
The diff coverage is 94.44%.

❗ Current head ec3d294 differs from pull request most recent head aaa6786. Consider uploading reports for the commit aaa6786 to get more accurate results

Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff           @@
##             main    #3104   +/-   ##
=======================================
  Coverage        ?   79.31%           
=======================================
  Files           ?      188           
  Lines           ?    13081           
  Branches        ?        0           
=======================================
  Hits            ?    10375           
  Misses          ?     2271           
  Partials        ?      435           
Files Changed Coverage Δ
modules/apps/transfer/module.go 46.55% <33.33%> (ø)
modules/apps/transfer/keeper/genesis.go 92.59% <100.00%> (ø)
modules/apps/transfer/keeper/keeper.go 91.83% <100.00%> (ø)
modules/apps/transfer/keeper/migrations.go 96.87% <100.00%> (ø)
modules/apps/transfer/keeper/relay.go 91.00% <100.00%> (ø)

Copy link
Contributor

@crodriguezvega crodriguezvega left a 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?

modules/apps/transfer/keeper/relay.go Outdated Show resolved Hide resolved
modules/apps/transfer/keeper/relay.go Outdated Show resolved Hide resolved
modules/apps/transfer/keeper/relay.go Outdated Show resolved Hide resolved
@0xmuralik
Copy link
Contributor Author

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 SetDenomTrace.

@crodriguezvega crodriguezvega added this to the v8.0.0 milestone Feb 6, 2023
@crodriguezvega
Copy link
Contributor

Sounds good. We can set MetaData in the initgenesis here after SetDenomTrace.

Yes, true, we should also do it in InitGenesis!

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.

Comment on lines 46 to 50

if !m.keeper.bankKeeper.HasDenomMetaData(ctx, newTrace.IBCDenom()) {
m.keeper.SetDenomMetaData(ctx, newTrace)
}

Copy link
Contributor

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

Copy link
Contributor Author

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.

Comment on lines 320 to 332
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),
Copy link
Contributor

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

Copy link
Contributor

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)

Copy link
Contributor Author

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.

Copy link
Contributor

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?

Copy link
Contributor

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

Copy link
Contributor

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!

Copy link
Contributor

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

Copy link
Contributor

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?

Copy link
Contributor

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

Copy link
Contributor

@colin-axner colin-axner left a 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 colin-axner changed the title add metadata after mint for IBC token add metadata for IBC tokens Feb 15, 2023
@colin-axner colin-axner changed the title add metadata for IBC tokens feat: add metadata for IBC tokens Feb 15, 2023
@0xmuralik 0xmuralik requested review from colin-axner and removed request for crodriguezvega February 16, 2023 06:10
@0xmuralik
Copy link
Contributor Author

@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.

Copy link
Contributor

@colin-axner colin-axner left a 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

modules/apps/transfer/keeper/migrations_test.go Outdated Show resolved Hide resolved
@@ -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) {
Copy link
Contributor

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?

Copy link
Contributor

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.

modules/apps/transfer/keeper/relay.go Outdated Show resolved Hide resolved
modules/apps/transfer/keeper/relay.go Outdated Show resolved Hide resolved
modules/apps/transfer/keeper/migrations.go Show resolved Hide resolved
modules/apps/transfer/keeper/genesis.go Outdated Show resolved Hide resolved
modules/apps/transfer/keeper/relay.go Outdated Show resolved Hide resolved
Comment on lines -388 to -397
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)
Copy link
Contributor

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...

Copy link
Contributor

@colin-axner colin-axner left a 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!

modules/apps/transfer/keeper/relay_test.go Outdated Show resolved Hide resolved
Copy link
Member

@damiannolan damiannolan left a 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

modules/apps/transfer/keeper/genesis_test.go Outdated Show resolved Hide resolved
modules/apps/transfer/keeper/keeper.go Outdated Show resolved Hide resolved
modules/apps/transfer/module.go Show resolved Hide resolved
Copy link
Contributor

@chatton chatton left a 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 👍

modules/apps/transfer/keeper/migrations.go Outdated Show resolved Hide resolved
modules/apps/transfer/keeper/migrations.go Outdated Show resolved Hide resolved
modules/apps/transfer/keeper/keeper.go Outdated Show resolved Hide resolved
@crodriguezvega
Copy link
Contributor

crodriguezvega commented Sep 11, 2023

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.

@crodriguezvega crodriguezvega merged commit 99c16eb into cosmos:main Sep 12, 2023
51 checks passed
@chatton chatton mentioned this pull request Sep 13, 2023
3 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

feat: return a human readable denomination for IBC vouchers when querying bank balances
9 participants