From aa1b6d1450dd7a7cc76d05a7ee3d75da8a0fd00a Mon Sep 17 00:00:00 2001 From: Amaury <1293565+amaurym@users.noreply.github.com> Date: Wed, 7 Sep 2022 16:21:10 +0200 Subject: [PATCH] docs(textual): custom `Msg` renderers (#12785) * Use RFC3339 for time * chore(textual): custom `Msg` renderers * Tweak * wording * wording * changelog * Update docs/architecture/adr-050-sign-mode-textual.md Co-authored-by: Robert Zaremba * Update docs/architecture/adr-050-sign-mode-textual.md Co-authored-by: Robert Zaremba * Update docs/architecture/adr-050-sign-mode-textual.md Co-authored-by: Robert Zaremba * Update docs/architecture/adr-050-sign-mode-textual.md Co-authored-by: Robert Zaremba * Update docs/architecture/adr-050-sign-mode-textual.md Co-authored-by: Robert Zaremba * Clearer bij check * Wording * Address reviews * Remove weeks from duration * Remove timestamp examples * Clear up about multiple * and > s * SPEC for > * tweak * tweak * Require signing over canonical bytes * Move example to correct subsection * wording * clarify tx hash malleability * Add ref to direct * revert all changes not related to Msg renderers * revert annex1 * revert * spacing * revert go.work.sum * remove regex mention * small tweaks * Fix headings * remove extra new line Co-authored-by: Robert Zaremba --- .../architecture/adr-050-sign-mode-textual.md | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/docs/architecture/adr-050-sign-mode-textual.md b/docs/architecture/adr-050-sign-mode-textual.md index 05f4085916..9bffa1d56f 100644 --- a/docs/architecture/adr-050-sign-mode-textual.md +++ b/docs/architecture/adr-050-sign-mode-textual.md @@ -6,6 +6,7 @@ - Feb 07, 2022: Draft read and concept-ACKed by the Ledger team. - May 16, 2022: Change status to Accepted. - Aug 11, 2022: Require signing over tx raw bytes. +- Sep 07, 2022: Add custom `Msg`-renderers. ## Status @@ -160,6 +161,44 @@ Grantee: cosmos1ghi...jkl End of transaction messages ``` +### 9. Custom `Msg` Renderers + +Application developers may choose to not follow default renderer value output for their own `Msg`s. In this case, they can implement their own custom `Msg` renderer. This is similar to [EIP4430](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-4430.md), where the smart contract developer chooses the description string to be shown to the end user. + +This is done by setting the `cosmos.msg.v1.textual.expert_custom_renderer` Protobuf option to a non-empty string. This option CAN ONLY be set on a Protobuf message representing transaction message object (implementing `sdk.Msg` interface). + +```proto +message MsgFooBar { + // Optional comments to describe in human-readable language the formatting + // rules of the custom renderer. + option (cosmos.msg.v1.textual.expert_custom_renderer) = ""; + + // proto fields +} +``` + +When this option is set on a `Msg`, a registered function will transform the `Msg` into an array of one or more strings, which MAY use the key/value format (described in point #3) with the expert field prefix (described in point #5) and arbitrary indentation (point #6). These strings MAY be rendered from a `Msg` field using a default value renderer, or they may be generated from several fields using custom logic. + +The `` is a string convention chosen by the application developer and is used to identify the custom `Msg` renderer. For example, the documentation or specification of this custom algorithm can reference this identifier. This identifier CAN have a versioned suffix (e.g. `_v1`) to adapt for future changes (which would be consensus-breaking). We also recommend adding Protobuf comments to describe in human language the custom logic used. + +Moreover, the renderer must provide 2 functions: one for formatting from Protobuf to string, and one for parsing string to Protobuf. These 2 functions are provided by the application developer. To satisfy point #1, these 2 functions MUST be bijective with each other. Bijectivity of these 2 functions will not be checked by the SDK at runtime. However, we strongly recommend the application developer to include a comprehensive suite in their app repo to test bijectivity, as to not introduce security bugs. A simple bijectivity test looks like: + +``` +// for renderer, msg, and ctx of the right type +keyvals, err := renderer.Format(ctx, msg) +if err != nil { + fail_check() +} +msg2, err := renderer.Parse(ctx, keyvals) +if err != nil { + fail_check() +} +if !proto.Equal(msg, msg2) { + fail_check() +} +pass_check() +``` + ### 10. Require signing over the `TxBody` and `AuthInfo` raw bytes Recall that the transaction bytes merklelized on chain are the Protobuf binary serialization of [TxRaw](https://github.com/cosmos/cosmos-sdk/blob/v0.46.0/proto/cosmos/tx/v1beta1/tx.proto#L33), which contains the `body_bytes` and `auth_info_bytes`. Moreover, the transaction hash is defined as the SHA256 hash of the `TxRaw` bytes. We require that the user signs over these bytes in SIGN_MODE_TEXTUAL, more specifically over the following string: