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(bank): reserve proto field numbers used by Penumbra #19298

Closed

Conversation

hdevalence
Copy link

Penumbra does not use the Cosmos SDK, but it does intend to interoperate with it. One point of interoperability is in asset metadata. The SDK provides a bank.Metadata message with metadata about an asset. Penumbra has a corresponding metadata message whose fields are a strict superset of the bank.Metadata message, so that Penumbra can parse SDK assets and vice versa.

This commit reserves two fields, by number and name, in order to ensure this compatibility can extend into the future.

First, it reserves a penumbra_asset_id field, numbered 1984.

Unlike the SDK, which identifies tokens by a "base denom" using the bank module, Penumbra identifies tokens using an "asset ID", an element of the finite field we use for SNARK proofs. For SDK-compatible assets, the asset ID is computed as a hash of the base denom string. Penumbra clients need to be able to match asset IDs with metadata, so we extended the metadata spec with an asset ID, and chose a name and field number we thought would be unlikely to conflict with the SDK.

The compatibility story is as follows: since the asset ID can be computed from the base denom, Penumbra's Rust libraries can parse SDK metadata without problems, computing the asset ID if it is missing and filling it in. And since proto parsers are expected to ignore unknown fields, SDK tooling can simply ignore and discard the unknown field.

(Why, then, include it at all? Because computing the asset ID involves Penumbra-specific cryptography, which may not be easily accessible in every language wishing to work with Penumbra data, such as Typescript).

Reserving this name and field number ensures that Penumbra and the SDK remain compatible going forward.

Second, it reserves an images field, numbered 1985.

This corresponds to the images structure defined in the cosmos asset registry:

https://github.com/cosmos/chain-registry/blob/42d163653ba1d32397d4dea48611c4b11f4c7e82/assetlist.schema.json#L136-L175

That repo notes that it is intended to be a strict superset of the SDK's proto definitions, to permit the possibility of upstreaming into the SDK at some future point. However, Penumbra's client tooling is entirely proto-based, so we cannot make use of the fields without upstreaming them into our protos, which we did. Because the json schema only specifies a name, not a field number, we had to choose a field number when we upstreamed the definitions. We chose 1985, to follow our previous extension.

Reserving the images field name with the same field number as Penumbra used ensures that, in the event that the SDK chose to upstream this extension into its protos, we would retain Penumbra<>SDK data format compatibility for both ProtoJSON and binary Protobuf encodings.

Penumbra does not use the Cosmos SDK, but it does intend to interoperate with
it. One point of interoperability is in asset metadata. The SDK provides a
`bank.Metadata` message with metadata about an asset. Penumbra has a
corresponding metadata message whose fields are a strict superset of the
`bank.Metadata` message, so that Penumbra can parse SDK assets and vice versa.

This commit reserves two fields, by number and name, in order to ensure this
compatibility can extend into the future.

First, it reserves a `penumbra_asset_id` field, numbered `1984`.

Unlike the SDK, which identifies tokens by a "base denom" using the bank
module, Penumbra identifies tokens using an "asset ID", an element of the
finite field we use for SNARK proofs.  For SDK-compatible assets, the asset ID
is computed as a hash of the base denom string.  Penumbra clients need to be
able to match asset IDs with metadata, so we extended the metadata spec with an
asset ID, and chose a name and field number we thought would be unlikely to
conflict with the SDK.

The compatibility story is as follows: since the asset ID can be computed from
the base denom, Penumbra's Rust libraries can parse SDK metadata without
problems, computing the asset ID if it is missing and filling it in.  And since
proto parsers are expected to ignore unknown fields, SDK tooling can simply
ignore and discard the unknown field.

(Why, then, include it at all? Because computing the asset ID involves
Penumbra-specific cryptography, which may not be easily accessible in every
language wishing to work with Penumbra data, such as Typescript).

Reserving this name and field number ensures that Penumbra and the SDK remain
compatible going forward.

Second, it reserves an `images` field, numbered `1985`.

This corresponds to the `images` structure defined in the cosmos asset registry:

https://github.com/cosmos/chain-registry/blob/42d163653ba1d32397d4dea48611c4b11f4c7e82/assetlist.schema.json#L136-L175

That repo notes that it is intended to be a strict superset of the SDK's proto
definitions, to permit the possibility of upstreaming into the SDK at some
future point.  However, Penumbra's client tooling is entirely proto-based, so
we cannot make use of the fields without upstreaming them into our protos,
which we did.  Because the json schema only specifies a name, not a field
number, we had to choose a field number when we upstreamed the definitions. We
chose 1985, to follow our previous extension.

Reserving the `images` field name with the same field number as Penumbra used
ensures that, in the event that the SDK chose to upstream this extension into
its protos, we would retain Penumbra<>SDK data format compatibility for both
ProtoJSON and binary Protobuf encodings.
@hdevalence hdevalence requested a review from a team as a code owner January 30, 2024 22:55
Copy link
Contributor

coderabbitai bot commented Jan 30, 2024

Walkthrough

The recent modifications to the bank.proto file incorporate reserved fields specifically for Penumbra asset ID and images. These updates are designed to enhance cross-system interoperability and ensure alignment with Penumbra's integration efforts. By embedding explanations for their use and ensuring backward compatibility, these changes signify a strategic move towards more seamless integration with Penumbra's protocol enhancements.

Changes

File Path Change Summary
proto/cosmos/bank/v1beta1/... Added reserved fields for Penumbra asset ID and images, with comments on usage and compatibility.

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

Share

Tips

Chat

There are 3 ways to chat with CodeRabbit:

Note: Auto-reply has been disabled for this repository by the repository owner. The CodeRabbit bot will not respond to your comments unless it is explicitly tagged.

  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit tests for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai generate interesting stats about this repository from git and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @coderabbitai read src/utils.ts and generate unit tests.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (invoked as PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger a review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai help to get help.

Additionally, you can add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

CodeRabbit Configration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • The JSON schema for the configuration file is available here.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/coderabbit-overrides.v2.json

CodeRabbit Discord Community

Join our Discord Community to get help, request features, and share feedback.

@hdevalence
Copy link
Author

This commit is incomplete, in particular I don't know how the SDK's proto tooling works and didn't try to update.

It's intended as a concrete starting point for discussion.

@tac0turtle
Copy link
Member

this seems a bit hacky to make "it work well enough". If we want to do this correctly we will need to identify if we should change this structure for sdk users then be able to get back to this.

Images here seems like something we should allow users to add. Lets talk to users and agree on overall changes that need to happen to this structure. The chain registry has evolved on it own due to lack of coordination on many fronts. We should try to align these sort of things.

@hdevalence
Copy link
Author

hdevalence commented Jan 31, 2024

Images here seems like something we should allow users to add.

I'm not sure I understand, allowing users to add images is exactly the point of this change!

To clarify, the goal is not that every on-chain instance of a Metadata has canonical images or something, it's so that client software can use a common data structure to handle all kinds of asset metadata -- whether that metadata is coming from the chain, or whether it's augmented by the client software.

As a concrete example, here's how we'll be using this in Penumbra. (Remember that all proto fields are optional, so they can be left unset).

  • The Penumbra app maintains an on-chain registry of known asset IDs, mapping AssetId => DenomMetadata. However, the on-chain DenomMetadata messages only contain the asset ID, the base denom, and only sometimes the units:
    • The native staking token also include a set of conventional units (1e6 display denom, similar to cosmos tokens)
    • When a validator is declared, it also registers that validator's delegation token (a native LST), and this has a set of conventional units matching the staking token
    • When tokens are transferred over IBC, they register an asset ID with the base denom only, and no units (e.g., transfer/channel-0/uosmo; we don't use the ibc/HASH format because we already have asset IDs)
  • None of the on-chain DenomMetadata instances have descriptions, images, etc.
  • A Penumbra user's data is scanned, decrypted, and locally indexed by their view server, an embeddable component running on the end-user device. For instance, the web wallet includes a view server implemented in Typescript, pcli includes the Rust view server, etc. Penumbra frontends are structured to treat the user's view server as a "local RPC", which hands back decrypted views of the user's data.
  • The view server maintains its own asset registry, mapping AssetId => DenomMetadata. This allows the client-side user software to add additional metadata, like descriptions, ticker symbols, images, etc. So, for instance, the view server could have configuration data that records the asset ID for transfer/channel-0/uosmo as having the symbol "OSMO" and an Osmosis logo image, while the asset ID for transfer/channel-1273/uosmo (let's say channel-1273 is a random channel to a scam chain) would be missing symbols, images, etc.
  • Frontend code operates on transaction views returned by the view server. These are pre-decrypted, pre-interpreted views of a shielded transaction that bundle the DenomMetadata internally. So, using the same example as above, a frontend would know to render the first asset as "OSMO" with an image and the second as "Unknown IBC Asset" or similar. And because the choice of how to render assets is made by the user's wallet software (which provides the view service), this logic applies to every single frontend the user connects to, frontend developers don't need to worry about asset presentation at all, because they can consume a common data format.

The key points here are:

  1. Adding fields to the proto definition doesn't require that they're chosen canonically on-chain. It just allows ecosystem tooling to interoperate about how to represent that data. In my view, even if there is no plan to make a canonical choice of what the data is, it would be helpful for the SDK to make a canonical choice of how that data should be represented by client tooling.
  2. This is the path that Penumbra chose, and so reserving the field names and numbers will preserve compatibility between the two stacks, even if the SDK chooses not to define these formats.

// Used by the cosmos asset registry to record images (logos), in json-schema extensions to this message.
// Reserved here to align with Penumbra's upstreaming of those extensions into its proto definitions.
reserved 1985;
reserved "images";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think this is fine, but i cant guarantee we or some other team may change it in the future

@julienrbrt
Copy link
Member

Could you fix the conflicts and run make proto-gen?

@julienrbrt julienrbrt changed the title bank: reserve proto field numbers used by Penumbra feat(bank): reserve proto field numbers used by Penumbra Feb 21, 2024
Copy link
Contributor

This pull request has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@github-actions github-actions bot added the Stale label Mar 23, 2024
@github-actions github-actions bot closed this Mar 28, 2024
@tac0turtle tac0turtle reopened this Mar 28, 2024
@github-actions github-actions bot removed the Stale label Mar 29, 2024
Copy link
Contributor

This pull request has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@github-actions github-actions bot added the Stale label Apr 28, 2024
@github-actions github-actions bot closed this May 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants