Skip to content

Commit

Permalink
feat: EIP191 sign mode (backport cosmos#11533) (cosmos#11545)
Browse files Browse the repository at this point in the history
* feat: EIP191 sign mode (cosmos#11533)

## Description

Adds [EIP-191](https://eips.ethereum.org/EIPS/eip-191) as a supported sign mode.

Ref: cosmos#10553 (comment)

---

### Author Checklist

*All items are required. Please add a note to the item if the item is not applicable and
please add links to any relevant follow up issues.*

I have...

- [ ] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title
- [ ] added `!` to the type prefix if API or client breaking change
- [x] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#pr-targeting))
- [ ] provided a link to the relevant issue or specification
- [ ] followed the guidelines for [building modules](https://github.com/cosmos/cosmos-sdk/blob/master/docs/building-modules)
- [ ] included the necessary unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#testing)
- [ ] added a changelog entry to `CHANGELOG.md`
- [ ] included comments for [documenting Go code](https://blog.golang.org/godoc)
- [ ] updated the relevant documentation or specification
- [ ] reviewed "Files changed" and left comments if necessary
- [ ] confirmed all CI checks have passed

### Reviewers Checklist

*All items are required. Please add a note if the item is not applicable and please add
your handle next to the items reviewed if you only reviewed selected items.*

I have...

- [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title
- [ ] confirmed `!` in the type prefix if API or client breaking change
- [ ] confirmed all author checklist items have been addressed
- [ ] reviewed state machine logic
- [ ] reviewed API design and naming
- [ ] reviewed documentation is accurate
- [ ] reviewed tests and test coverage
- [ ] manually tested (if applicable)

(cherry picked from commit dc66ddd)

# Conflicts:
#	CHANGELOG.md
#	api/cosmos/distribution/v1beta1/tx.pulsar.go
#	api/cosmos/tx/signing/v1beta1/signing.pulsar.go
#	client/cmd.go
#	client/flags/flags.go
#	client/tx/factory.go
#	go.sum
#	types/tx/signing/signing.pb.go
#	x/distribution/types/tx.pb.go

* fix conflicts

* fix conflicts++

Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com>
Co-authored-by: marbar3778 <marbar3778@yahoo.com>
  • Loading branch information
3 people authored and JeancarloBarrios committed Sep 28, 2024
1 parent 115a235 commit c2182e1
Show file tree
Hide file tree
Showing 7 changed files with 57 additions and 182 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ Ref: https://keepachangelog.com/en/1.0.0/

### Features

* (tx) [#\11533](https://github.com/cosmos/cosmos-sdk/pull/11533) Register [`EIP191`](https://eips.ethereum.org/EIPS/eip-191) as an available `SignMode` for chains to use.
* [\#11430](https://github.com/cosmos/cosmos-sdk/pull/11430) Introduce a new `grpc-only` flag, such that when enabled, will start the node in a query-only mode. Note, gRPC MUST be enabled with this flag.
* (x/bank) [\#11417](https://github.com/cosmos/cosmos-sdk/pull/11417) Introduce a new `SpendableBalances` gRPC query that retrieves an account's total (paginated) spendable balances.
* (x/bank) [\#10771](https://github.com/cosmos/cosmos-sdk/pull/10771) Add safety check on bank module perms to allow module-specific mint restrictions (e.g. only minting a certain denom).
Expand Down
11 changes: 2 additions & 9 deletions client/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -305,15 +305,8 @@ func readTxCommandFlags(clientCtx Context, flagSet *pflag.FlagSet) (Context, err
clientCtx = clientCtx.WithSignModeStr(flags.SignModeLegacyAminoJSON)
}
}

if !clientCtx.IsAux || flagSet.Changed(flags.FlagAux) {
isAux, _ := flagSet.GetBool(flags.FlagAux)
clientCtx = clientCtx.WithAux(isAux)
if isAux {
// If the user didn't explicitly set an --output flag, use JSON by default.
if clientCtx.OutputFormat == "" || !flagSet.Changed(flags.FlagOutput) {
clientCtx = clientCtx.WithOutputFormat(flags.OutputFormatJSON)
}
return clientCtx, nil
}

// GetClientQueryContext returns a Context from a command with fields set based on flags
// defined in AddQueryFlagsToCmd. An error is returned if any flag query fails.
Expand Down
4 changes: 0 additions & 4 deletions client/flags/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,6 @@ const (
SignModeDirect = "direct"
// SignModeLegacyAminoJSON is the value of the --sign-mode flag for SIGN_MODE_LEGACY_AMINO_JSON
SignModeLegacyAminoJSON = "amino-json"
// SignModeDirectAux is the value of the --sign-mode flag for SIGN_MODE_DIRECT_AUX
SignModeDirectAux = "direct-aux"
// SignModeTextual is the value of the --sign-mode flag for SIGN_MODE_TEXTUAL.
SignModeTextual = "textual"
// SignModeEIP191 is the value of the --sign-mode flag for SIGN_MODE_EIP_191
SignModeEIP191 = "eip-191"
)
Expand Down
14 changes: 0 additions & 14 deletions client/tx/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,24 +63,10 @@ func NewFactoryCLI(clientCtx client.Context, flagSet *pflag.FlagSet) (Factory, e
signMode = signing.SignMode_SIGN_MODE_DIRECT
case flags.SignModeLegacyAminoJSON:
signMode = signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON
case flags.SignModeDirectAux:
signMode = signing.SignMode_SIGN_MODE_DIRECT_AUX
case flags.SignModeTextual:
signMode = signing.SignMode_SIGN_MODE_TEXTUAL
case flags.SignModeEIP191:
signMode = signing.SignMode_SIGN_MODE_EIP_191
}

var accNum, accSeq uint64
if clientCtx.Offline {
if flagSet.Changed(flags.FlagAccountNumber) && flagSet.Changed(flags.FlagSequence) {
accNum = clientCtx.Viper.GetUint64(flags.FlagAccountNumber)
accSeq = clientCtx.Viper.GetUint64(flags.FlagSequence)
} else {
return Factory{}, errors.New("account-number and sequence must be set in offline mode")
}
}

gasAdj := clientCtx.Viper.GetFloat64(flags.FlagGasAdjustment)
memo := clientCtx.Viper.GetString(flags.FlagNote)
timestampUnix := clientCtx.Viper.GetInt64(flags.FlagTimeoutTimestamp)
Expand Down
9 changes: 2 additions & 7 deletions proto/cosmos/tx/signing/v1beta1/signing.proto
Original file line number Diff line number Diff line change
Expand Up @@ -43,20 +43,15 @@ enum SignMode {

// SIGN_MODE_EIP_191 specifies the sign mode for EIP 191 signing on the Cosmos
// SDK. Ref: https://eips.ethereum.org/EIPS/eip-191
//
//
// Currently, SIGN_MODE_EIP_191 is registered as a SignMode enum variant,
// but is not implemented on the SDK by default. To enable EIP-191, you need
// to pass a custom `TxConfig` that has an implementation of
// `SignModeHandler` for EIP-191. The SDK may decide to fully support
// EIP-191 in the future.
//
// Since: cosmos-sdk 0.45.2
// Deprecated: post 0.47.x Sign mode refers to a method of encoding string data for
// signing, but in the SDK, it also refers to how to encode a transaction into a string.
// This opens the possibility for additional EIP191 sign modes, like SIGN_MODE_EIP_191_TEXTUAL,
// SIGN_MODE_EIP_191_LEGACY_JSON, and more.
// Each new EIP191 sign mode should be accompanied by an associated ADR.
SIGN_MODE_EIP_191 = 191 [deprecated = true];
SIGN_MODE_EIP_191 = 191;
}

// SignatureDescriptors wraps multiple SignatureDescriptor's.
Expand Down
87 changes: 38 additions & 49 deletions types/tx/signing/signing.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

113 changes: 14 additions & 99 deletions x/auth/tx/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,105 +69,20 @@ var DefaultSignModes = []signingtypes.SignMode{

// NewTxConfig returns a new protobuf TxConfig using the provided ProtoCodec and sign modes. The
// first enabled sign mode will become the default sign mode.
//
// NOTE: Use NewTxConfigWithOptions to provide a custom signing handler in case the sign mode
// is not supported by default (eg: SignMode_SIGN_MODE_EIP_191), or to enable SIGN_MODE_TEXTUAL.
//
// We prefer to use depinject to provide client.TxConfig, but we permit this constructor usage. Within the SDK,
// this constructor is primarily used in tests, but also sees usage in app chains like:
// https://github.com/evmos/evmos/blob/719363fbb92ff3ea9649694bd088e4c6fe9c195f/encoding/config.go#L37
func NewTxConfig(protoCodec codec.Codec, addressCodec, validatorAddressCodec address.Codec, enabledSignModes []signingtypes.SignMode, customSignModes ...txsigning.SignModeHandler,
) client.TxConfig {
txConfig, err := NewTxConfigWithOptions(protoCodec, ConfigOptions{
EnabledSignModes: enabledSignModes,
CustomSignModes: customSignModes,
SigningOptions: &txsigning.Options{
AddressCodec: addressCodec,
ValidatorAddressCodec: validatorAddressCodec,
},
})
if err != nil {
panic(err)
}
return txConfig
}

// NewSigningOptions returns signing options used by x/tx. This includes account and
// validator address prefix enabled codecs.
func NewSigningOptions(addressCodec, validatorAddressCodec address.Codec) *txsigning.Options {
return &txsigning.Options{
AddressCodec: addressCodec,
ValidatorAddressCodec: validatorAddressCodec,
}
}

// NewSigningHandlerMap returns a new txsigning.HandlerMap using the provided ConfigOptions.
// It is recommended to use types.InterfaceRegistry in the field ConfigOptions.FileResolver as shown in
// NewTxConfigWithOptions but this fn does not enforce it.
func NewSigningHandlerMap(configOpts ConfigOptions) (*txsigning.HandlerMap, error) {
var err error
if configOpts.SigningOptions == nil {
return nil, errors.New("signing options not provided")
}
if configOpts.SigningContext == nil {
configOpts.SigningContext, err = txsigning.NewContext(*configOpts.SigningOptions)
if err != nil {
return nil, err
}
}

signingOpts := configOpts.SigningOptions

if len(configOpts.EnabledSignModes) == 0 {
configOpts.EnabledSignModes = DefaultSignModes
}

lenSignModes := len(configOpts.EnabledSignModes)
handlers := make([]txsigning.SignModeHandler, lenSignModes+len(configOpts.CustomSignModes))
for i, m := range configOpts.EnabledSignModes {
var err error
switch m {
case signingtypes.SignMode_SIGN_MODE_DIRECT:
handlers[i] = &direct.SignModeHandler{}
case signingtypes.SignMode_SIGN_MODE_DIRECT_AUX:
handlers[i], err = directaux.NewSignModeHandler(directaux.SignModeHandlerOptions{
TypeResolver: signingOpts.TypeResolver,
SignersContext: configOpts.SigningContext,
})
if err != nil {
return nil, err
}
case signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON:
handlers[i] = aminojson.NewSignModeHandler(aminojson.SignModeHandlerOptions{
FileResolver: signingOpts.FileResolver,
TypeResolver: signingOpts.TypeResolver,
})
case signingtypes.SignMode_SIGN_MODE_TEXTUAL:
handlers[i], err = textual.NewSignModeHandler(textual.SignModeOptions{
CoinMetadataQuerier: configOpts.TextualCoinMetadataQueryFn,
FileResolver: signingOpts.FileResolver,
TypeResolver: signingOpts.TypeResolver,
})
if configOpts.TextualCoinMetadataQueryFn == nil {
return nil, errors.New("cannot enable SIGN_MODE_TEXTUAL without a TextualCoinMetadataQueryFn")
}
if err != nil {
return nil, err
}
}
}
for i, m := range configOpts.CustomSignModes {
handlers[i+lenSignModes] = m
}

handler := txsigning.NewHandlerMap(handlers...)
return handler, nil
}

// NewTxConfigWithOptions returns a new protobuf TxConfig using the provided ProtoCodec, ConfigOptions and
// custom sign mode handlers. If ConfigOptions is an empty struct then default values will be used.
func NewTxConfigWithOptions(protoCodec codec.Codec, configOptions ConfigOptions) (client.TxConfig, error) {
txConfig := &config{
// 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).
func NewTxConfig(protoCodec codec.ProtoCodecMarshaler, enabledSignModes []signingtypes.SignMode) client.TxConfig {
return NewTxConfigWithHandler(protoCodec, makeSignModeHandler(enabledSignModes))
}

// NewTxConfig returns a new protobuf TxConfig using the provided ProtoCodec and signing handler.
func NewTxConfigWithHandler(protoCodec codec.ProtoCodecMarshaler, handler signing.SignModeHandler) client.TxConfig {
return &config{
handler: handler,
decoder: DefaultTxDecoder(protoCodec),
encoder: DefaultTxEncoder(),
jsonDecoder: DefaultJSONTxDecoder(protoCodec),
jsonEncoder: DefaultJSONTxEncoder(protoCodec),
protoCodec: protoCodec,
decoder: configOptions.ProtoDecoder,
encoder: configOptions.ProtoEncoder,
Expand Down

0 comments on commit c2182e1

Please sign in to comment.