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 Textual SignModeHandler #14650

Merged
merged 12 commits into from
Jan 18, 2023
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ Ref: https://keepachangelog.com/en/1.0.0/

### Features

* (x/auth) [#14650](https://github.com/cosmos/cosmos-sdk/pull/14650) Add Textual SignModeHandler. It is however **NOT** enabled by default, and should only be used for **TESTING** purposes until `SIGN_MODE_TEXTUAL` is fully released.
* (cli) [#14655](https://github.com/cosmos/cosmos-sdk/pull/14655) Add a new command to list supported algos.
* (x/crisis) [#14588](https://github.com/cosmos/cosmos-sdk/pull/14588) Use CacheContext() in AssertInvariants()
* (client) [#14342](https://github.com/cosmos/cosmos-sdk/pull/14342) Add `simd config` command is now a sub-command, for setting, getting and migrating Cosmos SDK configuration files.
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ require (
cosmossdk.io/depinject v1.0.0-alpha.3
cosmossdk.io/errors v1.0.0-beta.7
cosmossdk.io/math v1.0.0-beta.4
cosmossdk.io/x/tx v0.1.0
github.com/99designs/keyring v1.2.1
github.com/armon/go-metrics v0.4.1
github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ cosmossdk.io/errors v1.0.0-beta.7 h1:gypHW76pTQGVnHKo6QBkb4yFOJjC+sUGRc5Al3Odj1w
cosmossdk.io/errors v1.0.0-beta.7/go.mod h1:mz6FQMJRku4bY7aqS/Gwfcmr/ue91roMEKAmDUDpBfE=
cosmossdk.io/math v1.0.0-beta.4 h1:JtKedVLGzA0vv84xjYmZ75RKG35Kf2WwcFu8IjRkIIw=
cosmossdk.io/math v1.0.0-beta.4/go.mod h1:An0MllWJY6PxibUpnwGk8jOm+a/qIxlKmL5Zyp9NnaM=
cosmossdk.io/x/tx v0.1.0 h1:uyyYVjG22B+jf54N803Z99Y1uPvfuNP3K1YShoCHYL8=
cosmossdk.io/x/tx v0.1.0/go.mod h1:qsDv7e1fSftkF16kpSAk+7ROOojyj+SC0Mz3ukI52EQ=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
filippo.io/edwards25519 v1.0.0-rc.1 h1:m0VOOB23frXZvAOK44usCgLWvtsxIoMCTBGJZlpmGfU=
filippo.io/edwards25519 v1.0.0-rc.1/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns=
Expand Down
4 changes: 3 additions & 1 deletion proto/cosmos/tx/signing/v1beta1/signing.proto
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ enum SignMode {

// SIGN_MODE_TEXTUAL is a future signing mode that will verify some
// human-readable textual representation on top of the binary representation
// from SIGN_MODE_DIRECT. It is currently not supported.
// from SIGN_MODE_DIRECT. It is currently experimental, and should be used
// for testing purposes only, until Textual is fully released. Please follow
// the tracking issue https://github.com/cosmos/cosmos-sdk/issues/11970.
SIGN_MODE_TEXTUAL = 2;

// SIGN_MODE_DIRECT_AUX specifies a signing mode which uses
Expand Down
1 change: 1 addition & 0 deletions simapp/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ require (
cloud.google.com/go/storage v1.27.0 // indirect
cosmossdk.io/collections v0.0.0-20230106101515-aeac21494476 // indirect
cosmossdk.io/errors v1.0.0-beta.7 // indirect
cosmossdk.io/x/tx v0.1.0 // indirect
filippo.io/edwards25519 v1.0.0-rc.1 // indirect
github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect
github.com/99designs/keyring v1.2.1 // indirect
Expand Down
2 changes: 2 additions & 0 deletions simapp/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ cosmossdk.io/math v1.0.0-beta.4 h1:JtKedVLGzA0vv84xjYmZ75RKG35Kf2WwcFu8IjRkIIw=
cosmossdk.io/math v1.0.0-beta.4/go.mod h1:An0MllWJY6PxibUpnwGk8jOm+a/qIxlKmL5Zyp9NnaM=
cosmossdk.io/tools/rosetta v0.2.0 h1:Ae499UiZ9yPNCXvjOBO/R9I1pksCJfxoqWauEZgA/gs=
cosmossdk.io/tools/rosetta v0.2.0/go.mod h1:3mn8QuE2wLUdTi77/gbDXdFqXZdBdiBJhgAWUTSXPv8=
cosmossdk.io/x/tx v0.1.0 h1:uyyYVjG22B+jf54N803Z99Y1uPvfuNP3K1YShoCHYL8=
cosmossdk.io/x/tx v0.1.0/go.mod h1:qsDv7e1fSftkF16kpSAk+7ROOojyj+SC0Mz3ukI52EQ=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
filippo.io/edwards25519 v1.0.0-rc.1 h1:m0VOOB23frXZvAOK44usCgLWvtsxIoMCTBGJZlpmGfU=
filippo.io/edwards25519 v1.0.0-rc.1/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns=
Expand Down
1 change: 1 addition & 0 deletions tests/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ require (
cosmossdk.io/collections v0.0.0-20230106101515-aeac21494476 // indirect
cosmossdk.io/core v0.4.1 // indirect
cosmossdk.io/errors v1.0.0-beta.7 // indirect
cosmossdk.io/x/tx v0.1.0 // indirect
filippo.io/edwards25519 v1.0.0-rc.1 // indirect
github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect
github.com/99designs/keyring v1.2.1 // indirect
Expand Down
2 changes: 2 additions & 0 deletions tests/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ cosmossdk.io/errors v1.0.0-beta.7 h1:gypHW76pTQGVnHKo6QBkb4yFOJjC+sUGRc5Al3Odj1w
cosmossdk.io/errors v1.0.0-beta.7/go.mod h1:mz6FQMJRku4bY7aqS/Gwfcmr/ue91roMEKAmDUDpBfE=
cosmossdk.io/math v1.0.0-beta.4 h1:JtKedVLGzA0vv84xjYmZ75RKG35Kf2WwcFu8IjRkIIw=
cosmossdk.io/math v1.0.0-beta.4/go.mod h1:An0MllWJY6PxibUpnwGk8jOm+a/qIxlKmL5Zyp9NnaM=
cosmossdk.io/x/tx v0.1.0 h1:uyyYVjG22B+jf54N803Z99Y1uPvfuNP3K1YShoCHYL8=
cosmossdk.io/x/tx v0.1.0/go.mod h1:qsDv7e1fSftkF16kpSAk+7ROOojyj+SC0Mz3ukI52EQ=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
filippo.io/edwards25519 v1.0.0-rc.1 h1:m0VOOB23frXZvAOK44usCgLWvtsxIoMCTBGJZlpmGfU=
filippo.io/edwards25519 v1.0.0-rc.1/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns=
Expand Down
20 changes: 18 additions & 2 deletions x/auth/tx/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package tx
import (
"fmt"

"cosmossdk.io/x/tx/textual"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
Expand All @@ -21,10 +22,25 @@ type config struct {

// NewTxConfig returns a new protobuf TxConfig using the provided ProtoCodec and sign modes. The
// first enabled sign mode will become the default sign mode.
amaury1093 marked this conversation as resolved.
Show resolved Hide resolved
//
// NOTE: Use NewTxConfigWithHandler to provide a custom signing handler in case the sign mode
// is not supported by default (eg: SignMode_SIGN_MODE_EIP_191).
// is not supported by default (eg: SignMode_SIGN_MODE_EIP_191). Use NewTxConfigWithTextual
// to enable SIGN_MODE_TEXTUAL (for testing purposes for now).
func NewTxConfig(protoCodec codec.ProtoCodecMarshaler, enabledSignModes []signingtypes.SignMode) client.TxConfig {
return NewTxConfigWithHandler(protoCodec, makeSignModeHandler(enabledSignModes))
for _, m := range enabledSignModes {
if m == signingtypes.SignMode_SIGN_MODE_TEXTUAL {
panic("cannot use NewTxConfig with SIGN_MODE_TEXTUAL enabled; please use NewTxConfigWithTextual")
}
}

return NewTxConfigWithHandler(protoCodec, makeSignModeHandler(enabledSignModes, textual.NewTextual(nil)))
}

// NewTxConfigWithTextual is like NewTxConfig with the ability to add
// a SIGN_MODE_TEXTUAL renderer. It is currently still EXPERIMENTAL, for should
// be used for TESTING purposes only, until Textual is fully released.
func NewTxConfigWithTextual(protoCodec codec.ProtoCodecMarshaler, enabledSignModes []signingtypes.SignMode, textual textual.Textual) client.TxConfig {
return NewTxConfigWithHandler(protoCodec, makeSignModeHandler(enabledSignModes, textual))
}

// NewTxConfig returns a new protobuf TxConfig using the provided ProtoCodec and signing handler.
Expand Down
63 changes: 60 additions & 3 deletions x/auth/tx/config/config.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
package tx

import (
"context"
"fmt"

"google.golang.org/grpc/codes"
grpcstatus "google.golang.org/grpc/status"

bankv1beta1 "cosmossdk.io/api/cosmos/bank/v1beta1"
txconfigv1 "cosmossdk.io/api/cosmos/tx/config/v1"
"cosmossdk.io/core/appmodule"
"cosmossdk.io/depinject"
"cosmossdk.io/x/tx/textual"
"github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/codec"
Expand All @@ -15,6 +21,7 @@ import (
"github.com/cosmos/cosmos-sdk/x/auth/posthandler"
"github.com/cosmos/cosmos-sdk/x/auth/tx"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
"github.com/cosmos/cosmos-sdk/x/bank/types"
feegrantkeeper "github.com/cosmos/cosmos-sdk/x/feegrant/keeper"
)

Expand All @@ -31,8 +38,11 @@ type TxInputs struct {
Config *txconfigv1.Config
ProtoCodecMarshaler codec.ProtoCodecMarshaler

AccountKeeper ante.AccountKeeper `optional:"true"`
BankKeeper authtypes.BankKeeper `optional:"true"`
AccountKeeper ante.AccountKeeper `optional:"true"`
// BankKeeper is the expected bank keeper to be passed to AnteHandlers
BankKeeper authtypes.BankKeeper `optional:"true"`
// TxBankKeeper is the expected bank keeper to be passed to Textual
TxBankKeeper BankKeeper
FeeGrantKeeper feegrantkeeper.Keeper `optional:"true"`
}

Expand All @@ -45,7 +55,8 @@ type TxOutputs struct {
}

func ProvideModule(in TxInputs) TxOutputs {
txConfig := tx.NewTxConfig(in.ProtoCodecMarshaler, tx.DefaultSignModes)
textual := newTextualWithBankKeeper(in.TxBankKeeper)
txConfig := tx.NewTxConfigWithTextual(in.ProtoCodecMarshaler, tx.DefaultSignModes, textual)

baseAppOption := func(app *baseapp.BaseApp) {
// AnteHandlers
Expand Down Expand Up @@ -109,3 +120,49 @@ func newAnteHandler(txConfig client.TxConfig, in TxInputs) (sdk.AnteHandler, err

return anteHandler, nil
}

// newTextualWithBankKeeper creates a new Textual struct using the given
// BankKeeper to retrieve coin metadata.
func newTextualWithBankKeeper(bk BankKeeper) textual.Textual {
textual := textual.NewTextual(func(ctx context.Context, denom string) (*bankv1beta1.Metadata, error) {
res, err := bk.DenomMetadata(ctx, &types.QueryDenomMetadataRequest{Denom: denom})
if err != nil {
status, ok := grpcstatus.FromError(err)
if !ok {
return nil, err
}

// This means we didn't find any metadata for this denom. Returning
// empty metadata.
if status.Code() == codes.NotFound {
return nil, nil
}

return nil, err
}

m := &bankv1beta1.Metadata{
Base: res.Metadata.Base,
Display: res.Metadata.Display,
// fields below are not strictly needed by Textual
// but added here for completeness.
Description: res.Metadata.Description,
Name: res.Metadata.Name,
Symbol: res.Metadata.Symbol,
Uri: res.Metadata.URI,
UriHash: res.Metadata.URIHash,
}
m.DenomUnits = make([]*bankv1beta1.DenomUnit, len(res.Metadata.DenomUnits))
for i, d := range res.Metadata.DenomUnits {
m.DenomUnits[i] = &bankv1beta1.DenomUnit{
Denom: d.Denom,
Exponent: d.Exponent,
Aliases: d.Aliases,
}
}

return m, nil
})

return textual
}
12 changes: 12 additions & 0 deletions x/auth/tx/config/expected_keepers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package tx

import (
"context"

"github.com/cosmos/cosmos-sdk/x/bank/types"
)

// BankKeeper defines the contract needed for tx-related APIs
type BankKeeper interface {
DenomMetadata(c context.Context, req *types.QueryDenomMetadataRequest) (*types.QueryDenomMetadataResponse, error)
}
11 changes: 10 additions & 1 deletion x/auth/tx/mode_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package tx
import (
"fmt"

"cosmossdk.io/x/tx/textual"
signingtypes "github.com/cosmos/cosmos-sdk/types/tx/signing"
"github.com/cosmos/cosmos-sdk/x/auth/signing"
)
Expand All @@ -12,11 +13,17 @@ var DefaultSignModes = []signingtypes.SignMode{
signingtypes.SignMode_SIGN_MODE_DIRECT,
signingtypes.SignMode_SIGN_MODE_DIRECT_AUX,
signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON,
// We currently don't add SIGN_MODE_TEXTUAL as part of the default sign
// modes, as it's not released yet (including the Ledger app). However,
// textual's sign mode handler is already available in this package. If you
// want to use textual for **TESTING** purposes, feel free to create a
// handler that includes SIGN_MODE_TEXTUAL.
// ref: Tracking issue for SIGN_MODE_TEXTUAL https://github.com/cosmos/cosmos-sdk/issues/11970
}

// makeSignModeHandler returns the default protobuf SignModeHandler supporting
// SIGN_MODE_DIRECT, SIGN_MODE_DIRECT_AUX and SIGN_MODE_LEGACY_AMINO_JSON.
func makeSignModeHandler(modes []signingtypes.SignMode) signing.SignModeHandler {
func makeSignModeHandler(modes []signingtypes.SignMode, txt textual.Textual) signing.SignModeHandler {
if len(modes) < 1 {
panic(fmt.Errorf("no sign modes enabled"))
}
Expand All @@ -29,6 +36,8 @@ func makeSignModeHandler(modes []signingtypes.SignMode) signing.SignModeHandler
handlers[i] = signModeDirectHandler{}
case signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON:
handlers[i] = signModeLegacyAminoJSONHandler{}
case signingtypes.SignMode_SIGN_MODE_TEXTUAL:
handlers[i] = signModeTextualHandler{t: txt}
case signingtypes.SignMode_SIGN_MODE_DIRECT_AUX:
handlers[i] = signModeDirectAuxHandler{}
default:
Expand Down
71 changes: 71 additions & 0 deletions x/auth/tx/textual.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package tx

import (
"context"
"fmt"

"cosmossdk.io/x/tx/textual"
signingtypes "github.com/cosmos/cosmos-sdk/types/tx/signing"
"google.golang.org/protobuf/types/known/anypb"

txsigning "cosmossdk.io/x/tx/signing"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth/signing"
)

// signModeTextualHandler defines the SIGN_MODE_TEXTUAL SignModeHandler.
// It is currently not enabled by default, but you can enable it manually
// for TESTING purposes. It will be enabled once SIGN_MODE_TEXTUAL is fully
// released, see https://github.com/cosmos/cosmos-sdk/issues/11970.
type signModeTextualHandler struct {
t textual.Textual
}

var _ signing.SignModeHandler = signModeTextualHandler{}

// DefaultMode implements SignModeHandler.DefaultMode
func (signModeTextualHandler) DefaultMode() signingtypes.SignMode {
return signingtypes.SignMode_SIGN_MODE_TEXTUAL
}

// Modes implements SignModeHandler.Modes
func (signModeTextualHandler) Modes() []signingtypes.SignMode {
return []signingtypes.SignMode{signingtypes.SignMode_SIGN_MODE_TEXTUAL}
}

// GetSignBytes implements SignModeHandler.GetSignBytes
func (h signModeTextualHandler) GetSignBytes(mode signingtypes.SignMode, data signing.SignerData, tx sdk.Tx) ([]byte, error) {
panic("SIGN_MODE_TEXTUAL needs GetSignBytesWithContext")
}

// GetSignBytesWithContext implements SignModeHandler.GetSignBytesWithContext
func (h signModeTextualHandler) GetSignBytesWithContext(ctx context.Context, mode signingtypes.SignMode, data signing.SignerData, tx sdk.Tx) ([]byte, error) {
if mode != signingtypes.SignMode_SIGN_MODE_TEXTUAL {
return nil, fmt.Errorf("expected %s, got %s", signingtypes.SignMode_SIGN_MODE_TEXTUAL, mode)
}

protoTx, ok := tx.(*wrapper)
if !ok {
return nil, fmt.Errorf("can only handle a protobuf Tx, got %T", tx)
}

bodyBz := protoTx.getBodyBytes()
authInfoBz := protoTx.getAuthInfoBytes()

pbAny, err := codectypes.NewAnyWithValue(data.PubKey)
if err != nil {
return nil, err
}

return h.t.GetSignBytes(ctx, bodyBz, authInfoBz, txsigning.SignerData{
Address: data.Address,
ChainId: data.ChainID,
AccountNumber: data.AccountNumber,
Sequence: data.Sequence,
PubKey: &anypb.Any{
TypeUrl: pbAny.TypeUrl,
Value: pbAny.Value,
},
})
}
1 change: 1 addition & 0 deletions x/nft/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ require (

require (
cosmossdk.io/collections v0.0.0-20230106101515-aeac21494476 // indirect
cosmossdk.io/x/tx v0.1.0 // indirect
filippo.io/edwards25519 v1.0.0-rc.1 // indirect
github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect
github.com/99designs/keyring v1.2.1 // indirect
Expand Down
2 changes: 2 additions & 0 deletions x/nft/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ cosmossdk.io/errors v1.0.0-beta.7 h1:gypHW76pTQGVnHKo6QBkb4yFOJjC+sUGRc5Al3Odj1w
cosmossdk.io/errors v1.0.0-beta.7/go.mod h1:mz6FQMJRku4bY7aqS/Gwfcmr/ue91roMEKAmDUDpBfE=
cosmossdk.io/math v1.0.0-beta.4 h1:JtKedVLGzA0vv84xjYmZ75RKG35Kf2WwcFu8IjRkIIw=
cosmossdk.io/math v1.0.0-beta.4/go.mod h1:An0MllWJY6PxibUpnwGk8jOm+a/qIxlKmL5Zyp9NnaM=
cosmossdk.io/x/tx v0.1.0 h1:uyyYVjG22B+jf54N803Z99Y1uPvfuNP3K1YShoCHYL8=
cosmossdk.io/x/tx v0.1.0/go.mod h1:qsDv7e1fSftkF16kpSAk+7ROOojyj+SC0Mz3ukI52EQ=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
filippo.io/edwards25519 v1.0.0-rc.1 h1:m0VOOB23frXZvAOK44usCgLWvtsxIoMCTBGJZlpmGfU=
filippo.io/edwards25519 v1.0.0-rc.1/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns=
Expand Down
2 changes: 1 addition & 1 deletion x/tx/textual/any.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func (ar anyValueRenderer) Format(ctx context.Context, v protoreflect.Value) ([]

internalMsg, err := anymsg.UnmarshalNew()
if err != nil {
return nil, err
return nil, fmt.Errorf("error unmarshalling any %s: %w", anymsg.TypeUrl, err)
}
vr, err := ar.tr.GetMessageValueRenderer(internalMsg.ProtoReflect().Descriptor())
if err != nil {
Expand Down