From 86b88b1ace7e97b7f8e20cae81593c7ece9b46a7 Mon Sep 17 00:00:00 2001 From: Matt Kocubinski Date: Thu, 20 Apr 2023 11:20:21 -0500 Subject: [PATCH] refactor!: use x/tx/signing in client.TxConfig (#15822) --- .gitignore | 3 +- CHANGELOG.md | 5 + UPGRADING.md | 6 + baseapp/block_gas_test.go | 17 ++- baseapp/msg_service_router_test.go | 9 +- baseapp/testutil/messages.pb.go | 51 +++++---- baseapp/testutil/messages.proto | 3 + client/tx/tx.go | 14 ++- client/tx/tx_test.go | 11 +- client/tx_config.go | 3 +- go.mod | 3 +- go.sum | 6 +- server/grpc/server.go | 8 +- simapp/go.mod | 3 +- simapp/go.sum | 6 +- simapp/simd/cmd/root.go | 14 +-- tests/e2e/auth/suite.go | 2 +- tests/e2e/authz/tx.go | 2 + tests/e2e/feegrant/suite.go | 2 + tests/e2e/group/tx.go | 2 + tests/go.mod | 2 +- tests/go.sum | 4 +- testutil/sims/tx_helpers.go | 11 +- testutil/testdata/testpb/tx.proto | 3 + testutil/testdata/testpb/tx.pulsar.go | 64 ++++++----- testutil/testdata/tx.pb.go | 45 ++++---- testutil/testnet/genesis.go | 6 +- tools/rosetta/converter.go | 12 +- tools/rosetta/go.mod | 6 +- tools/rosetta/go.sum | 8 +- types/registry/registry.go | 52 +++++++++ x/auth/ante/ante.go | 4 +- x/auth/ante/feegrant_test.go | 15 ++- x/auth/ante/sigverify.go | 49 ++++++-- x/auth/ante/sigverify_test.go | 30 +++-- x/auth/ante/testutil_test.go | 10 +- x/auth/client/cli/tx_multisign.go | 75 +++++++++++-- x/auth/client/cli/validate_sigs.go | 45 +++++++- x/auth/signing/verify.go | 144 ++++++++++++++++++++---- x/auth/tx/aux_test.go | 24 ++-- x/auth/tx/config.go | 67 +++++++++-- x/auth/tx/config/config.go | 156 +++++++++++++++++++++++--- x/auth/tx/config/textual.go | 107 ------------------ x/auth/tx/direct_test.go | 17 ++- x/auth/tx/mode_handler.go | 70 ++++++------ x/auth/tx/testutil/suite.go | 22 ++-- x/authz/client/cli/tx_test.go | 4 +- x/group/client/cli/tx_test.go | 5 +- 48 files changed, 848 insertions(+), 379 deletions(-) create mode 100644 types/registry/registry.go delete mode 100644 x/auth/tx/config/textual.go diff --git a/.gitignore b/.gitignore index e6893eaeeb6..e74d19bc514 100644 --- a/.gitignore +++ b/.gitignore @@ -35,6 +35,7 @@ coverage.txt sim_log_file x/genutil/config x/genutil/data +*.fail # Vagrant .vagrant/ @@ -60,4 +61,4 @@ debug_container.log *.out *.synctex.gz /x/genutil/config/priv_validator_key.json -/x/genutil/data/priv_validator_state.json \ No newline at end of file +/x/genutil/data/priv_validator_state.json diff --git a/CHANGELOG.md b/CHANGELOG.md index d3fc751ed8e..b6101c64783 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -163,6 +163,11 @@ Ref: https://keepachangelog.com/en/1.0.0/ * `AminoCodec` is marked as deprecated. * (x/crisis) [#15852](https://github.com/cosmos/cosmos-sdk/pull/15852) Crisis keeper now takes a instance of the address codec to be able to decode user addresses * (x/slashing) [#15875](https://github.com/cosmos/cosmos-sdk/pull/15875) `x/slashing.NewAppModule` now requires an `InterfaceRegistry` parameter. +* (client) [#15822](https://github.com/cosmos/cosmos-sdk/pull/15822) The return type of the interface method `TxConfig.SignModeHandler` has been changed to `x/tx/signing.HandlerMap`. +* (x/auth) [#15822](https://github.com/cosmos/cosmos-sdk/pull/15822) The type of struct field `ante.HandlerOptions.SignModeHandler` has been changed to `x/tx/signing.HandlerMap`. + * The signature of `NewSigVerificationDecorator` has been changed to accept a `x/tx/signing.HandlerMap`. + * The signature of `VerifySignature` has been changed to accept a `x/tx/signing.HandlerMap` and other structs from `x/tx` as arguments. + * The signature of `NewTxConfigWithTextual` has been deprecated and its signature changed to accept a `SignModeOptions`. ### Client Breaking Changes diff --git a/UPGRADING.md b/UPGRADING.md index 891c6dcba7c..f2fafaa33a1 100644 --- a/UPGRADING.md +++ b/UPGRADING.md @@ -93,6 +93,10 @@ References to `types/store.go` which contained aliases for store types have been The `store` module is extracted to have a separate go.mod file which allows it be a standalone module. All the store imports are now renamed to use `cosmossdk.io/store` instead of `github.com/cosmos/cosmos-sdk/store` across the SDK. +#### Client + +The return type of the interface method `TxConfig.SignModeHandler()` has been changed from `x/auth/signing.SignModeHandler` to `x/tx/signing.HandlerMap`. This change is transparent to most users as the `TxConfig` interface is typically implemented by private `x/auth/tx.config` struct (as returned by `auth.NewTxConfig`) which has been updated to return the new type. If users have implemented their own `TxConfig` interface, they will need to update their implementation to return the new type. + ### Modules #### `**all**` @@ -105,6 +109,8 @@ It is now recommended to validate message directly in the message server. When t Methods in the `AccountKeeper` now use `context.Context` instead of `sdk.Context`. Any module that has an interface for it will need to update and re-generate mocks if needed. +For ante handler construction via `ante.NewAnteHandler`, the field `ante.HandlerOptions.SignModeHandler` has been updated to `x/tx/signing/HandlerMap` from `x/auth/signing/SignModeHandler`. Callers typically fetch this value from `client.TxConfig.SignModeHandler()` (which is also changed) so this change should be transparent to most users. + #### `x/capability` Capability was moved to [IBC-GO](https://github.com/cosmos/ibc-go). IBC V8 will contain the necessary changes to incorporate the new module location diff --git a/baseapp/block_gas_test.go b/baseapp/block_gas_test.go index 9c2ddd1c3c2..105cb4f2906 100644 --- a/baseapp/block_gas_test.go +++ b/baseapp/block_gas_test.go @@ -5,15 +5,15 @@ import ( "math" "testing" - "cosmossdk.io/depinject" - "cosmossdk.io/log" - sdkmath "cosmossdk.io/math" abci "github.com/cometbft/cometbft/abci/types" cmtjson "github.com/cometbft/cometbft/libs/json" cmtproto "github.com/cometbft/cometbft/proto/tendermint/types" dbm "github.com/cosmos/cosmos-db" "github.com/stretchr/testify/require" + "cosmossdk.io/depinject" + "cosmossdk.io/log" + sdkmath "cosmossdk.io/math" store "cosmossdk.io/store/types" baseapptestutil "github.com/cosmos/cosmos-sdk/baseapp/testutil" @@ -191,6 +191,10 @@ func TestBaseApp_BlockGas(t *testing.T) { } func createTestTx(txConfig client.TxConfig, txBuilder client.TxBuilder, privs []cryptotypes.PrivKey, accNums, accSeqs []uint64, chainID string) (xauthsigning.Tx, []byte, error) { + defaultSignMode, err := xauthsigning.APISignModeToInternal(txConfig.SignModeHandler().DefaultMode()) + if err != nil { + return nil, nil, err + } // First round: we gather all the signer infos. We use the "set empty // signature" hack to do that. var sigsV2 []signing.SignatureV2 @@ -198,7 +202,7 @@ func createTestTx(txConfig client.TxConfig, txBuilder client.TxBuilder, privs [] sigV2 := signing.SignatureV2{ PubKey: priv.PubKey(), Data: &signing.SingleSignatureData{ - SignMode: txConfig.SignModeHandler().DefaultMode(), + SignMode: defaultSignMode, Signature: nil, }, Sequence: accSeqs[i], @@ -206,7 +210,7 @@ func createTestTx(txConfig client.TxConfig, txBuilder client.TxBuilder, privs [] sigsV2 = append(sigsV2, sigV2) } - err := txBuilder.SetSignatures(sigsV2...) + err = txBuilder.SetSignatures(sigsV2...) if err != nil { return nil, nil, err } @@ -219,9 +223,10 @@ func createTestTx(txConfig client.TxConfig, txBuilder client.TxBuilder, privs [] ChainID: chainID, AccountNumber: accNums[i], Sequence: accSeqs[i], + PubKey: priv.PubKey(), } sigV2, err := tx.SignWithPrivKey( - context.TODO(), txConfig.SignModeHandler().DefaultMode(), signerData, + context.TODO(), defaultSignMode, signerData, txBuilder, priv, txConfig, accSeqs[i]) if err != nil { return nil, nil, err diff --git a/baseapp/msg_service_router_test.go b/baseapp/msg_service_router_test.go index 16f780e078f..3d0b637462c 100644 --- a/baseapp/msg_service_router_test.go +++ b/baseapp/msg_service_router_test.go @@ -1,6 +1,7 @@ package baseapp_test import ( + "context" "testing" abci "github.com/cometbft/cometbft/abci/types" @@ -94,6 +95,9 @@ func TestMsgService(t *testing.T) { // set the TxDecoder in the BaseApp for minimal tx simulations app.SetTxDecoder(txConfig.TxDecoder()) + defaultSignMode, err := authsigning.APISignModeToInternal(txConfig.SignModeHandler().DefaultMode()) + require.NoError(t, err) + testdata.RegisterInterfaces(interfaceRegistry) testdata.RegisterMsgServer( app.MsgServiceRouter(), @@ -114,7 +118,7 @@ func TestMsgService(t *testing.T) { sigV2 := signing.SignatureV2{ PubKey: priv.PubKey(), Data: &signing.SingleSignatureData{ - SignMode: txConfig.SignModeHandler().DefaultMode(), + SignMode: defaultSignMode, Signature: nil, }, Sequence: 0, @@ -128,9 +132,10 @@ func TestMsgService(t *testing.T) { ChainID: "test", AccountNumber: 0, Sequence: 0, + PubKey: priv.PubKey(), } sigV2, err = tx.SignWithPrivKey( - nil, txConfig.SignModeHandler().DefaultMode(), signerData, //nolint:staticcheck // SA1019: txConfig.SignModeHandler().DefaultMode() is deprecated: use txConfig.SignModeHandler().DefaultMode() instead. + context.TODO(), defaultSignMode, signerData, txBuilder, priv, txConfig, 0) require.NoError(t, err) err = txBuilder.SetSignatures(sigV2) diff --git a/baseapp/testutil/messages.pb.go b/baseapp/testutil/messages.pb.go index 6ab32a7ce41..533a7528921 100644 --- a/baseapp/testutil/messages.pb.go +++ b/baseapp/testutil/messages.pb.go @@ -7,6 +7,7 @@ import ( context "context" fmt "fmt" _ "github.com/cosmos/cosmos-sdk/codec/types" + _ "github.com/cosmos/cosmos-sdk/types/msgservice" _ "github.com/cosmos/gogoproto/gogoproto" grpc1 "github.com/cosmos/gogoproto/grpc" proto "github.com/cosmos/gogoproto/proto" @@ -276,30 +277,32 @@ func init() { func init() { proto.RegisterFile("messages.proto", fileDescriptor_4dc296cbfe5ffcd5) } var fileDescriptor_4dc296cbfe5ffcd5 = []byte{ - // 364 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x92, 0x4f, 0x6b, 0xe2, 0x50, - 0x14, 0xc5, 0xcd, 0x84, 0x51, 0xe7, 0xea, 0xcc, 0x48, 0x90, 0x21, 0x66, 0x20, 0x48, 0x16, 0x83, - 0x1b, 0x13, 0xc8, 0xec, 0xc6, 0xdd, 0x0c, 0x83, 0x2d, 0xc5, 0x0a, 0x29, 0x74, 0xd1, 0x8d, 0xbc, - 0xc4, 0xeb, 0x33, 0x98, 0xbc, 0x17, 0xf2, 0x5e, 0x0a, 0x7e, 0x8b, 0x7e, 0xac, 0x2e, 0x5d, 0x76, - 0x59, 0xf4, 0x8b, 0x94, 0xfc, 0xd3, 0x2e, 0x6a, 0x57, 0x5d, 0xe5, 0x9c, 0x73, 0xc9, 0xef, 0xe4, - 0x5e, 0x02, 0xdf, 0x62, 0x14, 0x82, 0x50, 0x14, 0x76, 0x92, 0x72, 0xc9, 0x8d, 0x3e, 0xe5, 0x94, - 0x17, 0xd2, 0xc9, 0x55, 0x95, 0x0e, 0x28, 0xe7, 0x34, 0x42, 0xa7, 0x70, 0x7e, 0xb6, 0x72, 0x08, - 0xdb, 0x96, 0x23, 0xeb, 0x1a, 0x60, 0x26, 0xe8, 0x3f, 0x9e, 0x31, 0x89, 0xa9, 0xa6, 0x43, 0x2b, - 0x28, 0xa5, 0xae, 0x0c, 0x95, 0x91, 0xea, 0xd5, 0x56, 0xfb, 0x05, 0xdf, 0x57, 0x24, 0x8c, 0x16, - 0x9c, 0x2d, 0xd6, 0x84, 0x2d, 0x23, 0x4c, 0xf5, 0x4f, 0x43, 0x65, 0xd4, 0xf6, 0xbe, 0xe6, 0xf1, - 0x9c, 0x5d, 0x94, 0xa1, 0x35, 0x87, 0xce, 0x89, 0xe7, 0x7e, 0x00, 0xd0, 0x00, 0x3d, 0x07, 0xa6, - 0x48, 0x24, 0x56, 0x58, 0x0f, 0x45, 0xc2, 0x99, 0x40, 0x6b, 0x56, 0x94, 0x5d, 0xe1, 0xf6, 0x96, - 0x44, 0x19, 0x6a, 0x3d, 0x50, 0x37, 0xb8, 0x2d, 0x8a, 0xba, 0x5e, 0x2e, 0xb5, 0x3e, 0x7c, 0xbe, - 0xcf, 0x47, 0x05, 0xba, 0xeb, 0x95, 0x46, 0xfb, 0x01, 0x4d, 0x11, 0x52, 0x86, 0xa9, 0xae, 0x0e, - 0x95, 0xd1, 0x17, 0xaf, 0x72, 0xd6, 0x4f, 0x18, 0x1c, 0xab, 0x6a, 0x68, 0xdd, 0xe5, 0xfe, 0x87, - 0x56, 0x7d, 0xa5, 0x3f, 0xd0, 0xbb, 0x64, 0x41, 0x8a, 0x31, 0x32, 0x59, 0x67, 0x1d, 0xfb, 0xb4, - 0xb6, 0x31, 0xb0, 0xcf, 0x7d, 0xb2, 0x3b, 0x85, 0xf6, 0xf1, 0x38, 0x93, 0x37, 0x38, 0xdd, 0x57, - 0x1c, 0xf7, 0x3d, 0xd0, 0x04, 0xda, 0xc7, 0xc5, 0x1d, 0x50, 0x6f, 0x50, 0x96, 0xef, 0xd6, 0xa1, - 0x61, 0xd8, 0x67, 0x97, 0xf9, 0x3b, 0x7d, 0xdc, 0x9b, 0xca, 0x6e, 0x6f, 0x2a, 0xcf, 0x7b, 0x53, - 0x79, 0x38, 0x98, 0x8d, 0xdd, 0xc1, 0x6c, 0x3c, 0x1d, 0xcc, 0xc6, 0xdd, 0x98, 0x86, 0x72, 0x9d, - 0xf9, 0x76, 0xc0, 0x63, 0x27, 0xe0, 0x22, 0xe6, 0xa2, 0x7a, 0x8c, 0xc5, 0x72, 0xe3, 0xf8, 0x44, - 0x20, 0x49, 0x12, 0x47, 0xa2, 0x90, 0x99, 0x0c, 0x23, 0xbf, 0x59, 0xfc, 0x45, 0xbf, 0x5f, 0x02, - 0x00, 0x00, 0xff, 0xff, 0x23, 0xdc, 0x12, 0x4d, 0x88, 0x02, 0x00, 0x00, + // 387 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x92, 0xcf, 0xca, 0xd3, 0x40, + 0x14, 0xc5, 0x1b, 0x83, 0xdf, 0x57, 0x6f, 0xab, 0x96, 0x50, 0x34, 0x8d, 0x10, 0x4a, 0x16, 0x52, + 0x84, 0x66, 0x30, 0xee, 0xda, 0x9d, 0x22, 0x55, 0x44, 0x0b, 0x11, 0x5c, 0x74, 0x53, 0x26, 0xe9, + 0xed, 0x34, 0x34, 0x99, 0x09, 0x99, 0x49, 0xa1, 0x5b, 0x9f, 0xc0, 0x47, 0xf1, 0x31, 0x5c, 0x76, + 0xe9, 0x52, 0xda, 0x85, 0xaf, 0x21, 0xf9, 0xd7, 0xba, 0xb0, 0xae, 0xbe, 0xd5, 0xdc, 0x73, 0x2e, + 0xf9, 0x9d, 0xcc, 0x61, 0xe0, 0x51, 0x82, 0x52, 0x52, 0x86, 0xd2, 0x4d, 0x33, 0xa1, 0x84, 0xf5, + 0x34, 0x14, 0x32, 0x11, 0x92, 0x24, 0x92, 0x91, 0xdd, 0xcb, 0xe2, 0xa8, 0x17, 0x7d, 0x26, 0x98, + 0x28, 0x47, 0x52, 0x4c, 0xb5, 0x3b, 0x60, 0x42, 0xb0, 0x18, 0x49, 0xa9, 0x82, 0x7c, 0x4d, 0x28, + 0xdf, 0x57, 0x2b, 0xe7, 0x13, 0xc0, 0x47, 0xc9, 0xde, 0x88, 0x9c, 0x2b, 0xcc, 0x0c, 0x13, 0x6e, + 0xc3, 0x6a, 0x34, 0xb5, 0xa1, 0x36, 0xd2, 0xfd, 0x46, 0x1a, 0xcf, 0xe1, 0xf1, 0x9a, 0x46, 0xf1, + 0x52, 0xf0, 0xe5, 0x86, 0xf2, 0x55, 0x8c, 0x99, 0x79, 0x6f, 0xa8, 0x8d, 0xda, 0xfe, 0xc3, 0xc2, + 0x9e, 0xf3, 0x77, 0x95, 0xe9, 0xcc, 0xa1, 0x73, 0xe1, 0x79, 0x77, 0x00, 0xb4, 0xc0, 0x2c, 0x80, + 0x19, 0x52, 0x85, 0x35, 0xd6, 0x47, 0x99, 0x0a, 0x2e, 0xd1, 0x59, 0x94, 0x61, 0x1f, 0x70, 0xff, + 0x85, 0xc6, 0x39, 0x1a, 0x3d, 0xd0, 0xb7, 0xb8, 0x2f, 0x83, 0xba, 0x7e, 0x31, 0x1a, 0x7d, 0xb8, + 0xbf, 0x2b, 0x56, 0x25, 0xba, 0xeb, 0x57, 0xc2, 0x78, 0x02, 0x37, 0x32, 0x62, 0x1c, 0x33, 0x53, + 0x1f, 0x6a, 0xa3, 0x07, 0x7e, 0xad, 0x26, 0x9d, 0xaf, 0xbf, 0xbf, 0xbf, 0xa8, 0x85, 0xf3, 0x0c, + 0x06, 0xe7, 0xdc, 0x26, 0xa1, 0x09, 0xf6, 0xde, 0xc2, 0x6d, 0x53, 0xd9, 0x04, 0x7a, 0xef, 0x79, + 0x98, 0x61, 0x82, 0x5c, 0x35, 0x5e, 0xc7, 0xbd, 0x74, 0x60, 0x0d, 0xdc, 0x6b, 0xff, 0xef, 0xcd, + 0xa0, 0x7d, 0x6e, 0x6a, 0xfa, 0x0f, 0x4e, 0xf7, 0x2f, 0x8e, 0xf7, 0x3f, 0xd0, 0x14, 0xda, 0xe7, + 0x16, 0x08, 0xe8, 0x9f, 0x51, 0x55, 0xdf, 0x36, 0xa6, 0x65, 0xb9, 0x57, 0x2f, 0xf3, 0x7a, 0xf6, + 0xe3, 0x68, 0x6b, 0x87, 0xa3, 0xad, 0xfd, 0x3a, 0xda, 0xda, 0xb7, 0x93, 0xdd, 0x3a, 0x9c, 0xec, + 0xd6, 0xcf, 0x93, 0xdd, 0x5a, 0x8c, 0x59, 0xa4, 0x36, 0x79, 0xe0, 0x86, 0x22, 0x21, 0xf5, 0x8b, + 0xab, 0x8e, 0xb1, 0x5c, 0x6d, 0x49, 0x40, 0x25, 0xd2, 0x34, 0x25, 0x0a, 0xa5, 0xca, 0x55, 0x14, + 0x07, 0x37, 0xe5, 0x93, 0x7a, 0xf5, 0x27, 0x00, 0x00, 0xff, 0xff, 0xea, 0x9d, 0x1c, 0xeb, 0xae, + 0x02, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. diff --git a/baseapp/testutil/messages.proto b/baseapp/testutil/messages.proto index 6a04a94e5c2..f5e1fb4b568 100644 --- a/baseapp/testutil/messages.proto +++ b/baseapp/testutil/messages.proto @@ -1,5 +1,6 @@ syntax = "proto3"; +import "cosmos/msg/v1/msg.proto"; import "gogoproto/gogo.proto"; import "google/protobuf/any.proto"; @@ -18,6 +19,8 @@ message MsgCounter2 { message MsgCreateCounterResponse {} message MsgKeyValue { + option (cosmos.msg.v1.signer) = "signer"; + bytes key = 1; bytes value = 2; string signer = 3; diff --git a/client/tx/tx.go b/client/tx/tx.go index 156b5763800..78de623a460 100644 --- a/client/tx/tx.go +++ b/client/tx/tx.go @@ -172,7 +172,8 @@ func SignWithPrivKey( var sigV2 signing.SignatureV2 // Generate the bytes to be signed. - signBytes, err := authsigning.GetSignBytesWithContext(txConfig.SignModeHandler(), ctx, signMode, signerData, txBuilder.GetTx()) + signBytes, err := authsigning.GetSignBytesAdapter( + ctx, txConfig.TxEncoder(), txConfig.SignModeHandler(), signMode, signerData, txBuilder.GetTx()) if err != nil { return sigV2, err } @@ -248,10 +249,14 @@ func Sign(ctx context.Context, txf Factory, name string, txBuilder client.TxBuil return errors.New("keybase must be set prior to signing a transaction") } + var err error signMode := txf.signMode if signMode == signing.SignMode_SIGN_MODE_UNSPECIFIED { // use the SignModeHandler's default mode if unspecified - signMode = txf.txConfig.SignModeHandler().DefaultMode() + signMode, err = authsigning.APISignModeToInternal(txf.txConfig.SignModeHandler().DefaultMode()) + if err != nil { + return err + } } k, err := txf.keybase.Key(name) @@ -313,8 +318,9 @@ func Sign(ctx context.Context, txf Factory, name string, txBuilder client.TxBuil return err } - // Generate the bytes to be signed. - bytesToSign, err := authsigning.GetSignBytesWithContext(txf.txConfig.SignModeHandler(), ctx, signMode, signerData, txBuilder.GetTx()) + bytesToSign, err := authsigning.GetSignBytesAdapter( + ctx, txf.txConfig.TxEncoder(), txf.txConfig.SignModeHandler(), + signMode, signerData, txBuilder.GetTx()) if err != nil { return err } diff --git a/client/tx/tx_test.go b/client/tx/tx_test.go index 202ed022c51..20d0a642d86 100644 --- a/client/tx/tx_test.go +++ b/client/tx/tx_test.go @@ -6,10 +6,11 @@ import ( "strings" "testing" - sdkmath "cosmossdk.io/math" "github.com/stretchr/testify/require" "google.golang.org/grpc" + sdkmath "cosmossdk.io/math" + "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/tx" "github.com/cosmos/cosmos-sdk/codec" @@ -78,10 +79,12 @@ func TestCalculateGas(t *testing.T) { for _, tc := range testCases { stc := tc txCfg, _ := newTestTxConfig() + defaultSignMode, err := signing.APISignModeToInternal(txCfg.SignModeHandler().DefaultMode()) + require.NoError(t, err) txf := tx.Factory{}. WithChainID("test-chain"). - WithTxConfig(txCfg).WithSignMode(txCfg.SignModeHandler().DefaultMode()) + WithTxConfig(txCfg).WithSignMode(defaultSignMode) t.Run(stc.name, func(t *testing.T) { mockClientCtx := mockContext{ @@ -104,6 +107,8 @@ func TestCalculateGas(t *testing.T) { func TestBuildSimTx(t *testing.T) { txCfg, cdc := newTestTxConfig() + defaultSignMode, err := signing.APISignModeToInternal(txCfg.SignModeHandler().DefaultMode()) + require.NoError(t, err) kb, err := keyring.New(t.Name(), "test", t.TempDir(), nil, cdc) require.NoError(t, err) @@ -119,7 +124,7 @@ func TestBuildSimTx(t *testing.T) { WithFees("50stake"). WithMemo("memo"). WithChainID("test-chain"). - WithSignMode(txCfg.SignModeHandler().DefaultMode()). + WithSignMode(defaultSignMode). WithKeybase(kb) msg := banktypes.NewMsgSend(sdk.AccAddress("from"), sdk.AccAddress("to"), nil) diff --git a/client/tx_config.go b/client/tx_config.go index 5c5fd2695e4..2d56976a63b 100644 --- a/client/tx_config.go +++ b/client/tx_config.go @@ -1,6 +1,7 @@ package client import ( + txsigning "cosmossdk.io/x/tx/signing" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/tx" signingtypes "github.com/cosmos/cosmos-sdk/types/tx/signing" @@ -27,7 +28,7 @@ type ( NewTxBuilder() TxBuilder WrapTxBuilder(sdk.Tx) (TxBuilder, error) - SignModeHandler() signing.SignModeHandler + SignModeHandler() *txsigning.HandlerMap } // TxBuilder defines an interface which an application-defined concrete transaction diff --git a/go.mod b/go.mod index 34c64d17247..6c0a46fbe6a 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( cosmossdk.io/log v1.0.0 cosmossdk.io/math v1.0.0 cosmossdk.io/store v0.1.0-alpha.1.0.20230328185921-37ba88872dbc - cosmossdk.io/x/tx v0.5.1-0.20230407182919-057d2e09bd63 + cosmossdk.io/x/tx v0.5.5 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 @@ -114,6 +114,7 @@ require ( github.com/hashicorp/go-plugin v1.4.9 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/hashicorp/yamux v0.1.1 // indirect + github.com/iancoleman/strcase v0.2.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jmhodges/levigo v1.0.0 // indirect github.com/klauspost/compress v1.16.5 // indirect diff --git a/go.sum b/go.sum index 96680cc745d..07d27288072 100644 --- a/go.sum +++ b/go.sum @@ -51,8 +51,8 @@ cosmossdk.io/math v1.0.0 h1:ro9w7eKx23om2tZz/VM2Pf+z2WAbGX1yDQQOJ6iGeJw= cosmossdk.io/math v1.0.0/go.mod h1:Ygz4wBHrgc7g0N+8+MrnTfS9LLn9aaTGa9hKopuym5k= cosmossdk.io/store v0.1.0-alpha.1.0.20230328185921-37ba88872dbc h1:9piuA+NYmhe+SyMPtMoboLw/djgDbrI3dD5TG020Tnk= cosmossdk.io/store v0.1.0-alpha.1.0.20230328185921-37ba88872dbc/go.mod h1:UFF5rmjN7WYVfxo6ArdY/l1+yyWMURBWOmSJypGqFHQ= -cosmossdk.io/x/tx v0.5.1-0.20230407182919-057d2e09bd63 h1:zHqj2VwZ/MStFmR7SUe/7gErOFhL9v2rkjmWPB/st34= -cosmossdk.io/x/tx v0.5.1-0.20230407182919-057d2e09bd63/go.mod h1:Oh3Kh+IPOfMEILNxVd2e8SLqRrIjYHpdGBfDg4ghU/k= +cosmossdk.io/x/tx v0.5.5 h1:9XG3KOrqObt7Rw7KhT7fiqRd6EepUfmA9ERa8CHj1WM= +cosmossdk.io/x/tx v0.5.5/go.mod h1:Oh3Kh+IPOfMEILNxVd2e8SLqRrIjYHpdGBfDg4ghU/k= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= filippo.io/edwards25519 v1.0.0 h1:0wAIcmJUqRdI8IJ/3eGi5/HwXZWPujYXXlkrQogz0Ek= filippo.io/edwards25519 v1.0.0/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= @@ -494,6 +494,8 @@ github.com/huandu/skiplist v1.2.0 h1:gox56QD77HzSC0w+Ws3MH3iie755GBJU1OER3h5VsYw github.com/huandu/skiplist v1.2.0/go.mod h1:7v3iFjLcSAzO4fN5B8dvebvo/qsfumiLiDXMrPiHF9w= github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= github.com/hydrogen18/memlistener v0.0.0-20200120041712-dcc25e7acd91/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= +github.com/iancoleman/strcase v0.2.0 h1:05I4QRnGpI0m37iZQRuskXh+w77mr6Z41lwQzuHLwW0= +github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= diff --git a/server/grpc/server.go b/server/grpc/server.go index d133fe451f1..51bcf3f445b 100644 --- a/server/grpc/server.go +++ b/server/grpc/server.go @@ -5,9 +5,10 @@ import ( "fmt" "net" - "cosmossdk.io/log" "google.golang.org/grpc" + "cosmossdk.io/log" + "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/server/config" @@ -44,8 +45,9 @@ func NewGRPCServer(clientCtx client.Context, app types.Application, cfg config.G // time. err := reflection.Register(grpcSrv, reflection.Config{ SigningModes: func() map[string]int32 { - modes := make(map[string]int32, len(clientCtx.TxConfig.SignModeHandler().Modes())) - for _, m := range clientCtx.TxConfig.SignModeHandler().Modes() { + supportedModes := clientCtx.TxConfig.SignModeHandler().SupportedModes() + modes := make(map[string]int32, len(supportedModes)) + for _, m := range supportedModes { modes[m.String()] = (int32)(m) } diff --git a/simapp/go.mod b/simapp/go.mod index 179f6e42636..3a3efaf3116 100644 --- a/simapp/go.mod +++ b/simapp/go.mod @@ -38,7 +38,7 @@ require ( cloud.google.com/go/storage v1.30.0 // indirect cosmossdk.io/collections v0.1.0 // indirect cosmossdk.io/errors v1.0.0-beta.7 // indirect - cosmossdk.io/x/tx v0.5.1-0.20230407182919-057d2e09bd63 // indirect + cosmossdk.io/x/tx v0.5.5 // indirect filippo.io/edwards25519 v1.0.0 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect github.com/99designs/keyring v1.2.1 // indirect @@ -122,6 +122,7 @@ require ( github.com/hashicorp/yamux v0.1.1 // indirect github.com/hdevalence/ed25519consensus v0.1.0 // indirect github.com/huandu/skiplist v1.2.0 // indirect + github.com/iancoleman/strcase v0.2.0 // indirect github.com/improbable-eng/grpc-web v0.15.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect diff --git a/simapp/go.sum b/simapp/go.sum index 193ca3c08cb..93e2139c21c 100644 --- a/simapp/go.sum +++ b/simapp/go.sum @@ -202,8 +202,8 @@ cosmossdk.io/log v1.0.0 h1:NGKZ/A5rd4PduDfoscgABklX557PWjQINbosZy/m3Jk= cosmossdk.io/log v1.0.0/go.mod h1:CwX9BLiBruZb7lzLlRr3R231d/fVPUXk8gAdV4LQap0= cosmossdk.io/math v1.0.0 h1:ro9w7eKx23om2tZz/VM2Pf+z2WAbGX1yDQQOJ6iGeJw= cosmossdk.io/math v1.0.0/go.mod h1:Ygz4wBHrgc7g0N+8+MrnTfS9LLn9aaTGa9hKopuym5k= -cosmossdk.io/x/tx v0.5.1-0.20230407182919-057d2e09bd63 h1:zHqj2VwZ/MStFmR7SUe/7gErOFhL9v2rkjmWPB/st34= -cosmossdk.io/x/tx v0.5.1-0.20230407182919-057d2e09bd63/go.mod h1:Oh3Kh+IPOfMEILNxVd2e8SLqRrIjYHpdGBfDg4ghU/k= +cosmossdk.io/x/tx v0.5.5 h1:9XG3KOrqObt7Rw7KhT7fiqRd6EepUfmA9ERa8CHj1WM= +cosmossdk.io/x/tx v0.5.5/go.mod h1:Oh3Kh+IPOfMEILNxVd2e8SLqRrIjYHpdGBfDg4ghU/k= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= filippo.io/edwards25519 v1.0.0 h1:0wAIcmJUqRdI8IJ/3eGi5/HwXZWPujYXXlkrQogz0Ek= filippo.io/edwards25519 v1.0.0/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= @@ -697,6 +697,8 @@ github.com/huandu/skiplist v1.2.0 h1:gox56QD77HzSC0w+Ws3MH3iie755GBJU1OER3h5VsYw github.com/huandu/skiplist v1.2.0/go.mod h1:7v3iFjLcSAzO4fN5B8dvebvo/qsfumiLiDXMrPiHF9w= github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= github.com/hydrogen18/memlistener v0.0.0-20200120041712-dcc25e7acd91/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= +github.com/iancoleman/strcase v0.2.0 h1:05I4QRnGpI0m37iZQRuskXh+w77mr6Z41lwQzuHLwW0= +github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= diff --git a/simapp/simd/cmd/root.go b/simapp/simd/cmd/root.go index 77bfddd68fd..84c798aa171 100644 --- a/simapp/simd/cmd/root.go +++ b/simapp/simd/cmd/root.go @@ -5,17 +5,16 @@ import ( "io" "os" - "cosmossdk.io/log" cmtcfg "github.com/cometbft/cometbft/config" dbm "github.com/cosmos/cosmos-db" "github.com/spf13/cobra" "github.com/spf13/viper" + "cosmossdk.io/log" "cosmossdk.io/simapp" "cosmossdk.io/simapp/params" confixcmd "cosmossdk.io/tools/confix/cmd" rosettaCmd "cosmossdk.io/tools/rosetta/cmd" - "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/config" "github.com/cosmos/cosmos-sdk/client/debug" @@ -82,18 +81,13 @@ func NewRootCmd() *cobra.Command { // This needs to go after ReadFromClientConfig, as that function // sets the RPC client needed for SIGN_MODE_TEXTUAL. - // - // TODO Currently, the TxConfig below doesn't include Textual, so - // an error will arise when using the --textual flag. - // ref: https://github.com/cosmos/cosmos-sdk/issues/11970 - txt, err := txmodule.NewTextualWithGRPCConn(initClientCtx) + opts, err := txmodule.NewSignModeOptionsWithMetadataQueryFn(txmodule.NewGRPCCoinMetadataQueryFn(initClientCtx)) if err != nil { return err } - txConfigWithTextual := tx.NewTxConfigWithTextual( + txConfigWithTextual := tx.NewTxConfigWithOptions( codec.NewProtoCodec(encodingConfig.InterfaceRegistry), - encodingConfig.TxConfig.SignModeHandler().Modes(), - txt, + opts, ) initClientCtx = initClientCtx.WithTxConfig(txConfigWithTextual) diff --git a/tests/e2e/auth/suite.go b/tests/e2e/auth/suite.go index 977203e17dc..3887ee44291 100644 --- a/tests/e2e/auth/suite.go +++ b/tests/e2e/auth/suite.go @@ -1510,7 +1510,7 @@ func (s *E2ETestSuite) TestTxWithoutPublicKey() { sigV2 := signing.SignatureV2{ PubKey: val1.PubKey, Data: &signing.SingleSignatureData{ - SignMode: txCfg.SignModeHandler().DefaultMode(), + SignMode: signing.SignMode_SIGN_MODE_DIRECT, Signature: nil, }, } diff --git a/tests/e2e/authz/tx.go b/tests/e2e/authz/tx.go index 7ff87f97f12..346897801e2 100644 --- a/tests/e2e/authz/tx.go +++ b/tests/e2e/authz/tx.go @@ -7,6 +7,8 @@ import ( "github.com/cosmos/gogoproto/proto" "github.com/stretchr/testify/suite" + // without this import amino json encoding will fail when resolving any types + _ "cosmossdk.io/api/cosmos/authz/v1beta1" "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/codec/address" "github.com/cosmos/cosmos-sdk/crypto/hd" diff --git a/tests/e2e/feegrant/suite.go b/tests/e2e/feegrant/suite.go index ab9ca482a45..9797f42ed00 100644 --- a/tests/e2e/feegrant/suite.go +++ b/tests/e2e/feegrant/suite.go @@ -9,6 +9,8 @@ import ( "github.com/cosmos/gogoproto/proto" "github.com/stretchr/testify/suite" + // without this import amino json encoding will fail when resolving any types + _ "cosmossdk.io/api/cosmos/feegrant/v1beta1" "cosmossdk.io/x/feegrant" "cosmossdk.io/x/feegrant/client/cli" "github.com/cosmos/cosmos-sdk/client" diff --git a/tests/e2e/group/tx.go b/tests/e2e/group/tx.go index c3e184db898..86c02e38c94 100644 --- a/tests/e2e/group/tx.go +++ b/tests/e2e/group/tx.go @@ -10,6 +10,8 @@ import ( "github.com/google/uuid" "github.com/stretchr/testify/suite" + // without this import amino json encoding will fail when resolving any types + _ "cosmossdk.io/api/cosmos/group/v1" "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/crypto/hd" "github.com/cosmos/cosmos-sdk/crypto/keyring" diff --git a/tests/go.mod b/tests/go.mod index 668edba4c77..8419aa4f899 100644 --- a/tests/go.mod +++ b/tests/go.mod @@ -13,7 +13,7 @@ require ( cosmossdk.io/x/evidence v0.1.0 cosmossdk.io/x/feegrant v0.0.0-20230117113717-50e7c4a4ceff cosmossdk.io/x/nft v0.0.0-20230113085233-fae3332d62fc - cosmossdk.io/x/tx v0.5.1 + cosmossdk.io/x/tx v0.5.5 cosmossdk.io/x/upgrade v0.0.0-20230127052425-54c8e1568335 github.com/cometbft/cometbft v0.37.1-0.20230411132551-3a91d155e664 github.com/cosmos/cosmos-db v1.0.0-rc.1 diff --git a/tests/go.sum b/tests/go.sum index 2de9f87725c..ded5f08b36f 100644 --- a/tests/go.sum +++ b/tests/go.sum @@ -202,8 +202,8 @@ cosmossdk.io/log v1.0.0 h1:NGKZ/A5rd4PduDfoscgABklX557PWjQINbosZy/m3Jk= cosmossdk.io/log v1.0.0/go.mod h1:CwX9BLiBruZb7lzLlRr3R231d/fVPUXk8gAdV4LQap0= cosmossdk.io/math v1.0.0 h1:ro9w7eKx23om2tZz/VM2Pf+z2WAbGX1yDQQOJ6iGeJw= cosmossdk.io/math v1.0.0/go.mod h1:Ygz4wBHrgc7g0N+8+MrnTfS9LLn9aaTGa9hKopuym5k= -cosmossdk.io/x/tx v0.5.1 h1:OcHU8ex3JzxDjexSkMovBx8EnJXcqhrRt7msBq/3vqs= -cosmossdk.io/x/tx v0.5.1/go.mod h1:Oh3Kh+IPOfMEILNxVd2e8SLqRrIjYHpdGBfDg4ghU/k= +cosmossdk.io/x/tx v0.5.5 h1:9XG3KOrqObt7Rw7KhT7fiqRd6EepUfmA9ERa8CHj1WM= +cosmossdk.io/x/tx v0.5.5/go.mod h1:Oh3Kh+IPOfMEILNxVd2e8SLqRrIjYHpdGBfDg4ghU/k= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= filippo.io/edwards25519 v1.0.0 h1:0wAIcmJUqRdI8IJ/3eGi5/HwXZWPujYXXlkrQogz0Ek= filippo.io/edwards25519 v1.0.0/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= diff --git a/testutil/sims/tx_helpers.go b/testutil/sims/tx_helpers.go index e6daeb06cc8..415ea292be4 100644 --- a/testutil/sims/tx_helpers.go +++ b/testutil/sims/tx_helpers.go @@ -26,7 +26,10 @@ func GenSignedMockTx(r *rand.Rand, txConfig client.TxConfig, msgs []sdk.Msg, fee // create a random length memo memo := simulation.RandStringOfLength(r, simulation.RandIntBetween(r, 0, 100)) - signMode := txConfig.SignModeHandler().DefaultMode() + signMode, err := authsign.APISignModeToInternal(txConfig.SignModeHandler().DefaultMode()) + if err != nil { + return nil, err + } // 1st round: set SignatureV2 with empty signatures, to set correct // signer infos. @@ -41,7 +44,7 @@ func GenSignedMockTx(r *rand.Rand, txConfig client.TxConfig, msgs []sdk.Msg, fee } tx := txConfig.NewTxBuilder() - err := tx.SetMsgs(msgs...) + err = tx.SetMsgs(msgs...) if err != nil { return nil, err } @@ -63,7 +66,9 @@ func GenSignedMockTx(r *rand.Rand, txConfig client.TxConfig, msgs []sdk.Msg, fee PubKey: p.PubKey(), } - signBytes, err := authsign.GetSignBytesWithContext(txConfig.SignModeHandler(), context.Background(), signMode, signerData, tx.GetTx()) + signBytes, err := authsign.GetSignBytesAdapter( + context.Background(), txConfig.TxEncoder(), txConfig.SignModeHandler(), signMode, signerData, + tx.GetTx()) if err != nil { panic(err) } diff --git a/testutil/testdata/testpb/tx.proto b/testutil/testdata/testpb/tx.proto index 464e3390478..72df915b136 100644 --- a/testutil/testdata/testpb/tx.proto +++ b/testutil/testdata/testpb/tx.proto @@ -1,6 +1,7 @@ syntax = "proto3"; package testpb; +import "amino/amino.proto"; import "gogoproto/gogo.proto"; import "testpb/testdata.proto"; import "cosmos/msg/v1/msg.proto"; @@ -30,5 +31,7 @@ message MsgCreateDogResponse { // https://github.com/cosmos/cosmos-sdk/issues/6213. message TestMsg { option (gogoproto.goproto_getters) = false; + option (cosmos.msg.v1.signer) = "signers"; + option (amino.name) = "testpb/TestMsg"; repeated string signers = 1; } diff --git a/testutil/testdata/testpb/tx.pulsar.go b/testutil/testdata/testpb/tx.pulsar.go index b0d65307662..5e4213c4802 100644 --- a/testutil/testdata/testpb/tx.pulsar.go +++ b/testutil/testdata/testpb/tx.pulsar.go @@ -2,6 +2,7 @@ package testpb import ( + _ "cosmossdk.io/api/amino" _ "cosmossdk.io/api/cosmos/msg/v1" fmt "fmt" runtime "github.com/cosmos/cosmos-proto/runtime" @@ -1545,36 +1546,39 @@ var File_testpb_tx_proto protoreflect.FileDescriptor var file_testpb_tx_proto_rawDesc = []byte{ 0x0a, 0x0f, 0x74, 0x65, 0x73, 0x74, 0x70, 0x62, 0x2f, 0x74, 0x78, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x12, 0x06, 0x74, 0x65, 0x73, 0x74, 0x70, 0x62, 0x1a, 0x14, 0x67, 0x6f, 0x67, 0x6f, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x67, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, - 0x15, 0x74, 0x65, 0x73, 0x74, 0x70, 0x62, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x64, 0x61, 0x74, 0x61, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x17, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x6d, - 0x73, 0x67, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x73, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, - 0x4f, 0x0a, 0x0c, 0x4d, 0x73, 0x67, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x6f, 0x67, 0x12, - 0x1d, 0x0a, 0x03, 0x64, 0x6f, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x74, - 0x65, 0x73, 0x74, 0x70, 0x62, 0x2e, 0x44, 0x6f, 0x67, 0x52, 0x03, 0x64, 0x6f, 0x67, 0x12, 0x14, - 0x0a, 0x05, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6f, - 0x77, 0x6e, 0x65, 0x72, 0x3a, 0x0a, 0x82, 0xe7, 0xb0, 0x2a, 0x05, 0x6f, 0x77, 0x6e, 0x65, 0x72, - 0x22, 0x2a, 0x0a, 0x14, 0x4d, 0x73, 0x67, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x6f, 0x67, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x29, 0x0a, 0x07, - 0x54, 0x65, 0x73, 0x74, 0x4d, 0x73, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x69, 0x67, 0x6e, 0x65, - 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, - 0x73, 0x3a, 0x04, 0x88, 0xa0, 0x1f, 0x00, 0x32, 0x4d, 0x0a, 0x03, 0x4d, 0x73, 0x67, 0x12, 0x3f, - 0x0a, 0x09, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x6f, 0x67, 0x12, 0x14, 0x2e, 0x74, 0x65, - 0x73, 0x74, 0x70, 0x62, 0x2e, 0x4d, 0x73, 0x67, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x6f, - 0x67, 0x1a, 0x1c, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x62, 0x2e, 0x4d, 0x73, 0x67, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x44, 0x6f, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x1a, - 0x05, 0x80, 0xe7, 0xb0, 0x2a, 0x01, 0x42, 0x8b, 0x01, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x2e, 0x74, - 0x65, 0x73, 0x74, 0x70, 0x62, 0x42, 0x07, 0x54, 0x78, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, - 0x5a, 0x3c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x73, - 0x6d, 0x6f, 0x73, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2d, 0x73, 0x64, 0x6b, 0x2f, 0x74, - 0x65, 0x73, 0x74, 0x75, 0x74, 0x69, 0x6c, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x64, 0x61, 0x74, 0x61, - 0x5f, 0x70, 0x75, 0x6c, 0x73, 0x61, 0x72, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x70, 0x62, 0xa2, 0x02, - 0x03, 0x54, 0x58, 0x58, 0xaa, 0x02, 0x06, 0x54, 0x65, 0x73, 0x74, 0x70, 0x62, 0xca, 0x02, 0x06, - 0x54, 0x65, 0x73, 0x74, 0x70, 0x62, 0xe2, 0x02, 0x12, 0x54, 0x65, 0x73, 0x74, 0x70, 0x62, 0x5c, - 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x06, 0x54, 0x65, - 0x73, 0x74, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6f, 0x12, 0x06, 0x74, 0x65, 0x73, 0x74, 0x70, 0x62, 0x1a, 0x11, 0x61, 0x6d, 0x69, 0x6e, 0x6f, + 0x2f, 0x61, 0x6d, 0x69, 0x6e, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x14, 0x67, 0x6f, + 0x67, 0x6f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x67, 0x6f, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x1a, 0x15, 0x74, 0x65, 0x73, 0x74, 0x70, 0x62, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x17, 0x63, 0x6f, 0x73, 0x6d, 0x6f, + 0x73, 0x2f, 0x6d, 0x73, 0x67, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x73, 0x67, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x22, 0x4f, 0x0a, 0x0c, 0x4d, 0x73, 0x67, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, + 0x6f, 0x67, 0x12, 0x1d, 0x0a, 0x03, 0x64, 0x6f, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x0b, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x62, 0x2e, 0x44, 0x6f, 0x67, 0x52, 0x03, 0x64, 0x6f, + 0x67, 0x12, 0x14, 0x0a, 0x05, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x3a, 0x0a, 0x82, 0xe7, 0xb0, 0x2a, 0x05, 0x6f, 0x77, + 0x6e, 0x65, 0x72, 0x22, 0x2a, 0x0a, 0x14, 0x4d, 0x73, 0x67, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x44, 0x6f, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, + 0x48, 0x0a, 0x07, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x73, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x69, + 0x67, 0x6e, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x73, 0x69, 0x67, + 0x6e, 0x65, 0x72, 0x73, 0x3a, 0x23, 0x88, 0xa0, 0x1f, 0x00, 0x82, 0xe7, 0xb0, 0x2a, 0x07, 0x73, + 0x69, 0x67, 0x6e, 0x65, 0x72, 0x73, 0x8a, 0xe7, 0xb0, 0x2a, 0x0e, 0x74, 0x65, 0x73, 0x74, 0x70, + 0x62, 0x2f, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x73, 0x67, 0x32, 0x4d, 0x0a, 0x03, 0x4d, 0x73, 0x67, + 0x12, 0x3f, 0x0a, 0x09, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x6f, 0x67, 0x12, 0x14, 0x2e, + 0x74, 0x65, 0x73, 0x74, 0x70, 0x62, 0x2e, 0x4d, 0x73, 0x67, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x44, 0x6f, 0x67, 0x1a, 0x1c, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x62, 0x2e, 0x4d, 0x73, 0x67, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x6f, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x1a, 0x05, 0x80, 0xe7, 0xb0, 0x2a, 0x01, 0x42, 0x8b, 0x01, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, + 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x62, 0x42, 0x07, 0x54, 0x78, 0x50, 0x72, 0x6f, 0x74, 0x6f, + 0x50, 0x01, 0x5a, 0x3c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, + 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2d, 0x73, 0x64, 0x6b, + 0x2f, 0x74, 0x65, 0x73, 0x74, 0x75, 0x74, 0x69, 0x6c, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x64, 0x61, + 0x74, 0x61, 0x5f, 0x70, 0x75, 0x6c, 0x73, 0x61, 0x72, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x70, 0x62, + 0xa2, 0x02, 0x03, 0x54, 0x58, 0x58, 0xaa, 0x02, 0x06, 0x54, 0x65, 0x73, 0x74, 0x70, 0x62, 0xca, + 0x02, 0x06, 0x54, 0x65, 0x73, 0x74, 0x70, 0x62, 0xe2, 0x02, 0x12, 0x54, 0x65, 0x73, 0x74, 0x70, + 0x62, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x06, + 0x54, 0x65, 0x73, 0x74, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/testutil/testdata/tx.pb.go b/testutil/testdata/tx.pb.go index b12e6fa2eb3..e2d416faa41 100644 --- a/testutil/testdata/tx.pb.go +++ b/testutil/testdata/tx.pb.go @@ -7,6 +7,7 @@ import ( context "context" fmt "fmt" _ "github.com/cosmos/cosmos-sdk/types/msgservice" + _ "github.com/cosmos/cosmos-sdk/types/tx/amino" _ "github.com/cosmos/gogoproto/gogoproto" grpc1 "github.com/cosmos/gogoproto/grpc" proto "github.com/cosmos/gogoproto/proto" @@ -173,27 +174,29 @@ func init() { func init() { proto.RegisterFile("testpb/tx.proto", fileDescriptor_1c54006dba274b2e) } var fileDescriptor_1c54006dba274b2e = []byte{ - // 313 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x2f, 0x49, 0x2d, 0x2e, - 0x29, 0x48, 0xd2, 0x2f, 0xa9, 0xd0, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x83, 0x08, 0x48, - 0x89, 0xa4, 0xe7, 0xa7, 0xe7, 0x83, 0x85, 0xf4, 0x41, 0x2c, 0x88, 0xac, 0x94, 0x28, 0x4c, 0x79, - 0x6a, 0x71, 0x49, 0x4a, 0x62, 0x49, 0x22, 0x54, 0x58, 0x3c, 0x39, 0xbf, 0x38, 0x37, 0xbf, 0x58, - 0x3f, 0xb7, 0x38, 0x5d, 0xbf, 0xcc, 0x10, 0x44, 0x41, 0x24, 0x94, 0xfc, 0xb9, 0x78, 0x7c, 0x8b, - 0xd3, 0x9d, 0x8b, 0x52, 0x13, 0x4b, 0x52, 0x5d, 0xf2, 0xd3, 0x85, 0x64, 0xb9, 0x98, 0x53, 0xf2, - 0xd3, 0x25, 0x18, 0x15, 0x18, 0x35, 0xb8, 0x8d, 0xb8, 0xf5, 0x20, 0xa6, 0xe9, 0xb9, 0xe4, 0xa7, - 0x07, 0x81, 0xc4, 0x85, 0x44, 0xb8, 0x58, 0xf3, 0xcb, 0xf3, 0x52, 0x8b, 0x24, 0x98, 0x14, 0x18, - 0x35, 0x38, 0x83, 0x20, 0x1c, 0x2b, 0xae, 0xa6, 0xe7, 0x1b, 0xb4, 0x20, 0x6c, 0x25, 0x2d, 0x2e, - 0x11, 0x64, 0x03, 0x83, 0x52, 0x8b, 0x0b, 0xf2, 0xf3, 0x8a, 0x53, 0x85, 0x84, 0xb8, 0x58, 0xf2, - 0x12, 0x73, 0x53, 0xc1, 0x26, 0x73, 0x06, 0x81, 0xd9, 0x4a, 0x9a, 0x5c, 0xec, 0x21, 0xa9, 0xc5, - 0x25, 0xbe, 0xc5, 0xe9, 0x42, 0x12, 0x5c, 0xec, 0xc5, 0x99, 0xe9, 0x79, 0xa9, 0x45, 0xc5, 0x12, - 0x8c, 0x0a, 0xcc, 0x1a, 0x9c, 0x41, 0x30, 0xae, 0x15, 0x4b, 0xc7, 0x02, 0x79, 0x06, 0x23, 0x5f, - 0x2e, 0x66, 0x90, 0x32, 0x7b, 0x2e, 0x4e, 0x84, 0x5b, 0x45, 0x60, 0xce, 0x43, 0xb6, 0x50, 0x4a, - 0x06, 0x9b, 0x28, 0xcc, 0x19, 0x52, 0xac, 0x0d, 0xcf, 0x37, 0x68, 0x31, 0x3a, 0x79, 0x9c, 0x78, - 0x24, 0xc7, 0x78, 0xe1, 0x91, 0x1c, 0xe3, 0x83, 0x47, 0x72, 0x8c, 0x13, 0x1e, 0xcb, 0x31, 0x5c, - 0x78, 0x2c, 0xc7, 0x70, 0xe3, 0xb1, 0x1c, 0x43, 0x94, 0x5e, 0x7a, 0x66, 0x49, 0x46, 0x69, 0x92, - 0x5e, 0x72, 0x7e, 0xae, 0x3e, 0x34, 0xd0, 0x20, 0x94, 0x6e, 0x71, 0x4a, 0x36, 0x38, 0x58, 0x4b, - 0x4b, 0x32, 0x73, 0xe0, 0xe1, 0x9b, 0xc4, 0x06, 0x0e, 0x47, 0x63, 0x40, 0x00, 0x00, 0x00, 0xff, - 0xff, 0x0a, 0x96, 0x8c, 0x83, 0xa8, 0x01, 0x00, 0x00, + // 337 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x90, 0x31, 0x4b, 0xc3, 0x40, + 0x14, 0xc7, 0x73, 0xd6, 0xb6, 0xe4, 0x2a, 0x8a, 0x21, 0x62, 0x08, 0x1a, 0x4b, 0x5d, 0x4a, 0xc0, + 0x1c, 0xd6, 0xad, 0x8b, 0xa0, 0x1d, 0xba, 0x14, 0x21, 0x38, 0xb9, 0xa5, 0xed, 0x71, 0x06, 0x4d, + 0x5e, 0xc9, 0xbb, 0xaa, 0xa3, 0x38, 0x89, 0x93, 0x1f, 0xc1, 0x8f, 0xd0, 0x8f, 0xe1, 0xd8, 0xd1, + 0x51, 0xda, 0xa1, 0x5f, 0x43, 0x72, 0x97, 0x68, 0x07, 0x97, 0xbc, 0xff, 0xfb, 0x3d, 0xf2, 0xbf, + 0xf7, 0xfe, 0x74, 0x47, 0x72, 0x94, 0x93, 0x21, 0x93, 0x4f, 0xc1, 0x24, 0x03, 0x09, 0x56, 0x4d, + 0x03, 0x77, 0x37, 0x4a, 0xe2, 0x14, 0x98, 0xfa, 0xea, 0x91, 0x6b, 0x0b, 0x10, 0xa0, 0x24, 0xcb, + 0x55, 0x41, 0xf7, 0x4a, 0x07, 0x8e, 0x72, 0x1c, 0xc9, 0xa8, 0xc0, 0xfb, 0x23, 0xc0, 0x04, 0x90, + 0x25, 0x28, 0xd8, 0xc3, 0x69, 0x5e, 0xf4, 0xa0, 0x75, 0x45, 0xb7, 0x06, 0x28, 0x2e, 0x33, 0x1e, + 0x49, 0xde, 0x03, 0x61, 0x1d, 0xd2, 0xca, 0x18, 0x84, 0x43, 0x9a, 0xa4, 0xdd, 0xe8, 0x34, 0x02, + 0xed, 0x16, 0xf4, 0x40, 0x84, 0x39, 0xb7, 0x6c, 0x5a, 0x85, 0xc7, 0x94, 0x67, 0xce, 0x46, 0x93, + 0xb4, 0xcd, 0x50, 0x37, 0x5d, 0xfa, 0xb2, 0x9a, 0xf9, 0x5a, 0xb7, 0x7c, 0x6a, 0xaf, 0x1b, 0x86, + 0x1c, 0x27, 0x90, 0x22, 0xb7, 0x2c, 0xba, 0x99, 0x46, 0x09, 0x57, 0xce, 0x66, 0xa8, 0x74, 0xab, + 0x4f, 0xeb, 0xd7, 0x1c, 0xe5, 0x00, 0x85, 0xe5, 0xd0, 0x3a, 0xc6, 0x22, 0xe5, 0x19, 0x3a, 0xa4, + 0x59, 0x69, 0x9b, 0x61, 0xd9, 0x76, 0x8f, 0x5f, 0x3f, 0x8e, 0x8c, 0xfc, 0x81, 0x92, 0xbc, 0xad, + 0x66, 0xfe, 0x76, 0x71, 0x66, 0xf1, 0x7b, 0x67, 0x40, 0x2b, 0xb9, 0xcb, 0x39, 0x35, 0xff, 0x4e, + 0xb1, 0xcb, 0xed, 0xd7, 0xf7, 0x71, 0x0f, 0xfe, 0xa3, 0xe5, 0x96, 0x6e, 0xf5, 0x79, 0x35, 0xf3, + 0xc9, 0x45, 0xff, 0x73, 0xe1, 0x91, 0xf9, 0xc2, 0x23, 0xdf, 0x0b, 0x8f, 0xbc, 0x2f, 0x3d, 0x63, + 0xbe, 0xf4, 0x8c, 0xaf, 0xa5, 0x67, 0xdc, 0x04, 0x22, 0x96, 0xb7, 0xd3, 0x61, 0x30, 0x82, 0x84, + 0x15, 0x99, 0xea, 0x72, 0x82, 0xe3, 0x3b, 0x95, 0xfa, 0x54, 0xc6, 0xf7, 0xbf, 0xf1, 0x0f, 0x6b, + 0x2a, 0xe6, 0xb3, 0x9f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x89, 0xf1, 0xc8, 0x3c, 0xda, 0x01, 0x00, + 0x00, } // Reference imports to suppress errors if they are not otherwise used. diff --git a/testutil/testnet/genesis.go b/testutil/testnet/genesis.go index 7b867dee736..bfc1755c816 100644 --- a/testutil/testnet/genesis.go +++ b/testutil/testnet/genesis.go @@ -1,6 +1,7 @@ package testnet import ( + "context" "encoding/json" "fmt" "strconv" @@ -140,7 +141,10 @@ func (b *GenesisBuilder) GenTx(privVal secp256k1.PrivKey, val cmttypes.GenesisVa } // Generate bytes to be signed. - bytesToSign, err := txConf.SignModeHandler().GetSignBytes( + bytesToSign, err := authsigning.GetSignBytesAdapter( + context.Background(), + txConf.TxEncoder(), + txConf.SignModeHandler(), signing.SignMode_SIGN_MODE_DIRECT, authsigning.SignerData{ ChainID: b.chainID, diff --git a/tools/rosetta/converter.go b/tools/rosetta/converter.go index 5146ef93c47..429add923a7 100644 --- a/tools/rosetta/converter.go +++ b/tools/rosetta/converter.go @@ -2,13 +2,11 @@ package rosetta import ( "bytes" + "context" "encoding/json" "fmt" "reflect" - sdkmath "cosmossdk.io/math" - crgerrs "cosmossdk.io/tools/rosetta/lib/errors" - crgtypes "cosmossdk.io/tools/rosetta/lib/types" rosettatypes "github.com/coinbase/rosetta-sdk-go/types" abci "github.com/cometbft/cometbft/abci/types" "github.com/cometbft/cometbft/crypto" @@ -16,6 +14,10 @@ import ( cmttypes "github.com/cometbft/cometbft/types" secp "github.com/decred/dcrd/dcrec/secp256k1/v4" + sdkmath "cosmossdk.io/math" + crgerrs "cosmossdk.io/tools/rosetta/lib/errors" + crgtypes "cosmossdk.io/tools/rosetta/lib/types" + sdkclient "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" codectypes "github.com/cosmos/cosmos-sdk/codec/types" @@ -113,7 +115,9 @@ func NewConverter(cdc *codec.ProtoCodec, ir codectypes.InterfaceRegistry, cfg sd txDecode: cfg.TxDecoder(), txEncode: cfg.TxEncoder(), bytesToSign: func(tx authsigning.Tx, signerData authsigning.SignerData) (b []byte, err error) { - bytesToSign, err := cfg.SignModeHandler().GetSignBytes(signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, signerData, tx) + bytesToSign, err := authsigning.GetSignBytesAdapter( + context.Background(), cfg.TxEncoder(), cfg.SignModeHandler(), + signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, signerData, tx) if err != nil { return nil, err } diff --git a/tools/rosetta/go.mod b/tools/rosetta/go.mod index 21bf562827b..5298e59c903 100644 --- a/tools/rosetta/go.mod +++ b/tools/rosetta/go.mod @@ -23,7 +23,7 @@ require ( cosmossdk.io/depinject v1.0.0-alpha.3 // indirect cosmossdk.io/errors v1.0.0-beta.7 // indirect cosmossdk.io/store v0.1.0-alpha.1.0.20230328185921-37ba88872dbc // indirect - cosmossdk.io/x/tx v0.5.1-0.20230407182919-057d2e09bd63 // indirect + cosmossdk.io/x/tx v0.5.5 // indirect filippo.io/edwards25519 v1.0.0 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect github.com/99designs/keyring v1.2.1 // indirect @@ -82,6 +82,7 @@ require ( github.com/hashicorp/yamux v0.1.1 // indirect github.com/hdevalence/ed25519consensus v0.1.0 // indirect github.com/huandu/skiplist v1.2.0 // indirect + github.com/iancoleman/strcase v0.2.0 // indirect github.com/improbable-eng/grpc-web v0.15.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/klauspost/compress v1.16.5 // indirect @@ -137,3 +138,6 @@ require ( pgregory.net/rapid v0.5.5 // indirect sigs.k8s.io/yaml v1.3.0 // indirect ) + +// temp to use local version of cosmos-sdk while in dev +replace github.com/cosmos/cosmos-sdk => ../.. diff --git a/tools/rosetta/go.sum b/tools/rosetta/go.sum index e3ac72d3a2a..742944d15ac 100644 --- a/tools/rosetta/go.sum +++ b/tools/rosetta/go.sum @@ -51,8 +51,8 @@ cosmossdk.io/math v1.0.0 h1:ro9w7eKx23om2tZz/VM2Pf+z2WAbGX1yDQQOJ6iGeJw= cosmossdk.io/math v1.0.0/go.mod h1:Ygz4wBHrgc7g0N+8+MrnTfS9LLn9aaTGa9hKopuym5k= cosmossdk.io/store v0.1.0-alpha.1.0.20230328185921-37ba88872dbc h1:9piuA+NYmhe+SyMPtMoboLw/djgDbrI3dD5TG020Tnk= cosmossdk.io/store v0.1.0-alpha.1.0.20230328185921-37ba88872dbc/go.mod h1:UFF5rmjN7WYVfxo6ArdY/l1+yyWMURBWOmSJypGqFHQ= -cosmossdk.io/x/tx v0.5.1-0.20230407182919-057d2e09bd63 h1:zHqj2VwZ/MStFmR7SUe/7gErOFhL9v2rkjmWPB/st34= -cosmossdk.io/x/tx v0.5.1-0.20230407182919-057d2e09bd63/go.mod h1:Oh3Kh+IPOfMEILNxVd2e8SLqRrIjYHpdGBfDg4ghU/k= +cosmossdk.io/x/tx v0.5.5 h1:9XG3KOrqObt7Rw7KhT7fiqRd6EepUfmA9ERa8CHj1WM= +cosmossdk.io/x/tx v0.5.5/go.mod h1:Oh3Kh+IPOfMEILNxVd2e8SLqRrIjYHpdGBfDg4ghU/k= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= filippo.io/edwards25519 v1.0.0 h1:0wAIcmJUqRdI8IJ/3eGi5/HwXZWPujYXXlkrQogz0Ek= filippo.io/edwards25519 v1.0.0/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= @@ -172,8 +172,6 @@ github.com/cosmos/cosmos-db v1.0.0-rc.1 h1:SjnT8B6WKMW9WEIX32qMhnEEKcI7ZP0+G1Sa9 github.com/cosmos/cosmos-db v1.0.0-rc.1/go.mod h1:Dnmk3flSf5lkwCqvvjNpoxjpXzhxnCAFzKHlbaForso= github.com/cosmos/cosmos-proto v1.0.0-beta.3 h1:VitvZ1lPORTVxkmF2fAp3IiA61xVwArQYKXTdEcpW6o= github.com/cosmos/cosmos-proto v1.0.0-beta.3/go.mod h1:t8IASdLaAq+bbHbjq4p960BvcTqtwuAxid3b/2rOD6I= -github.com/cosmos/cosmos-sdk v0.46.0-beta2.0.20230418140744-0dde947d0ab7 h1:+Q/K5pdQdQjp21gIxlQgGy4dOZk9gUBSQmJCYIf1bWA= -github.com/cosmos/cosmos-sdk v0.46.0-beta2.0.20230418140744-0dde947d0ab7/go.mod h1:BPvKPN63ettXrpz67uM1rHEqX/UVVkAfceFCPyp217E= github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y= github.com/cosmos/go-bip39 v1.0.0 h1:pcomnQdrdH22njcAatO0yWojsUnCO3y2tNoV1cb6hHY= github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4xuwvCdJw= @@ -467,6 +465,8 @@ github.com/huandu/skiplist v1.2.0 h1:gox56QD77HzSC0w+Ws3MH3iie755GBJU1OER3h5VsYw github.com/huandu/skiplist v1.2.0/go.mod h1:7v3iFjLcSAzO4fN5B8dvebvo/qsfumiLiDXMrPiHF9w= github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= github.com/hydrogen18/memlistener v0.0.0-20200120041712-dcc25e7acd91/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= +github.com/iancoleman/strcase v0.2.0 h1:05I4QRnGpI0m37iZQRuskXh+w77mr6Z41lwQzuHLwW0= +github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= diff --git a/types/registry/registry.go b/types/registry/registry.go new file mode 100644 index 00000000000..9fe5c8facc9 --- /dev/null +++ b/types/registry/registry.go @@ -0,0 +1,52 @@ +package registry + +import ( + "sync" + + "github.com/cosmos/gogoproto/proto" + "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/reflect/protoregistry" + + "cosmossdk.io/x/tx/signing" +) + +var ( + mergedRegistryOnce sync.Once + mergedRegistry *protoregistry.Files + _ signing.ProtoFileResolver = lazyProtoRegistry{} +) + +// lazyProtoRegistry is a lazy loading wrapper around the global protobuf registry. +type lazyProtoRegistry struct{} + +func getRegistry() *protoregistry.Files { + var err error + mergedRegistryOnce.Do(func() { + mergedRegistry, err = proto.MergedRegistry() + if err != nil { + panic(err) + } + }) + return mergedRegistry +} + +func (l lazyProtoRegistry) FindFileByPath(s string) (protoreflect.FileDescriptor, error) { + reg := getRegistry() + return reg.FindFileByPath(s) +} + +func (l lazyProtoRegistry) FindDescriptorByName(name protoreflect.FullName) (protoreflect.Descriptor, error) { + reg := getRegistry() + return reg.FindDescriptorByName(name) +} + +func (l lazyProtoRegistry) RangeFiles(f func(protoreflect.FileDescriptor) bool) { + reg := getRegistry() + reg.RangeFiles(f) +} + +// MergedProtoRegistry returns a lazy loading wrapper around the global protobuf registry, a merged registry +// containing both gogo proto and pulsar types. +func MergedProtoRegistry() signing.ProtoFileResolver { + return lazyProtoRegistry{} +} diff --git a/x/auth/ante/ante.go b/x/auth/ante/ante.go index f3b4ebb6a1b..05c5eb10265 100644 --- a/x/auth/ante/ante.go +++ b/x/auth/ante/ante.go @@ -2,13 +2,13 @@ package ante import ( storetypes "cosmossdk.io/store/types" + txsigning "cosmossdk.io/x/tx/signing" errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/types/tx/signing" - authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing" "github.com/cosmos/cosmos-sdk/x/auth/types" ) @@ -18,7 +18,7 @@ type HandlerOptions struct { BankKeeper types.BankKeeper ExtensionOptionChecker ExtensionOptionChecker FeegrantKeeper FeegrantKeeper - SignModeHandler authsigning.SignModeHandler + SignModeHandler *txsigning.HandlerMap SigGasConsumer func(meter storetypes.GasMeter, sig signing.SignatureV2, params types.Params) error TxFeeChecker TxFeeChecker } diff --git a/x/auth/ante/feegrant_test.go b/x/auth/ante/feegrant_test.go index 3cee6394f6b..31cebeaec98 100644 --- a/x/auth/ante/feegrant_test.go +++ b/x/auth/ante/feegrant_test.go @@ -1,6 +1,7 @@ package ante_test import ( + "context" "errors" "math/rand" "testing" @@ -168,14 +169,18 @@ func TestDeductFeesNoDelegation(t *testing.T) { var defaultGenTxGas uint64 = 10000000 tx, err := genTxWithFeeGranter(protoTxCfg, msgs, fee, defaultGenTxGas, suite.ctx.ChainID(), accNums, seqs, feeAcc, privs...) require.NoError(t, err) - _, err = feeAnteHandler(suite.ctx, tx, false) // tests only feegrant ante + txBytes, err := protoTxCfg.TxEncoder()(tx) + require.NoError(t, err) + bytesCtx := suite.ctx.WithTxBytes(txBytes) + require.NoError(t, err) + _, err = feeAnteHandler(bytesCtx, tx, false) // tests only feegrant ante if tc.valid { require.NoError(t, err) } else { testutil.AssertError(t, err, tc.err, tc.errMsg) } - _, err = anteHandlerStack(suite.ctx, tx, false) // tests while stack + _, err = anteHandlerStack(bytesCtx, tx, false) // tests whole stack if tc.valid { require.NoError(t, err) } else { @@ -200,7 +205,7 @@ func genTxWithFeeGranter(gen client.TxConfig, msgs []sdk.Msg, feeAmt sdk.Coins, memo := simulation.RandStringOfLength(r, simulation.RandIntBetween(r, 0, 100)) - signMode := gen.SignModeHandler().DefaultMode() + signMode := signing.SignMode_SIGN_MODE_DIRECT // 1st round: set SignatureV2 with empty signatures, to set correct // signer infos. @@ -234,8 +239,10 @@ func genTxWithFeeGranter(gen client.TxConfig, msgs []sdk.Msg, feeAmt sdk.Coins, ChainID: chainID, AccountNumber: accNums[i], Sequence: accSeqs[i], + PubKey: p.PubKey(), } - signBytes, err := gen.SignModeHandler().GetSignBytes(signMode, signerData, tx.GetTx()) + signBytes, err := authsign.GetSignBytesAdapter( + context.Background(), gen.TxEncoder(), gen.SignModeHandler(), signMode, signerData, tx.GetTx()) if err != nil { panic(err) } diff --git a/x/auth/ante/sigverify.go b/x/auth/ante/sigverify.go index 6891b0ed873..c38ec4741d9 100644 --- a/x/auth/ante/sigverify.go +++ b/x/auth/ante/sigverify.go @@ -6,8 +6,14 @@ import ( "encoding/hex" "fmt" + "google.golang.org/protobuf/types/known/anypb" + errorsmod "cosmossdk.io/errors" storetypes "cosmossdk.io/store/types" + "cosmossdk.io/x/tx/decode" + txsigning "cosmossdk.io/x/tx/signing" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + "github.com/cosmos/cosmos-sdk/types/registry" "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" kmultisig "github.com/cosmos/cosmos-sdk/crypto/keys/multisig" @@ -194,17 +200,17 @@ func (sgcd SigGasConsumeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simula return next(ctx, tx, simulate) } -// Verify all signatures for a tx and return an error if any are invalid. Note, +// SigVerificationDecorator verifies all signatures for a tx and return an error if any are invalid. Note, // the SigVerificationDecorator will not check signatures on ReCheck. // // CONTRACT: Pubkeys are set in context for all signers before this decorator runs // CONTRACT: Tx must implement SigVerifiableTx interface type SigVerificationDecorator struct { ak AccountKeeper - signModeHandler authsigning.SignModeHandler + signModeHandler *txsigning.HandlerMap } -func NewSigVerificationDecorator(ak AccountKeeper, signModeHandler authsigning.SignModeHandler) SigVerificationDecorator { +func NewSigVerificationDecorator(ak AccountKeeper, signModeHandler *txsigning.HandlerMap) SigVerificationDecorator { return SigVerificationDecorator{ ak: ak, signModeHandler: signModeHandler, @@ -279,17 +285,38 @@ func (svd SigVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simul if !genesis { accNum = acc.GetAccountNumber() } - signerData := authsigning.SignerData{ - Address: acc.GetAddress().String(), - ChainID: chainID, - AccountNumber: accNum, - Sequence: acc.GetSequence(), - PubKey: pubKey, - } // no need to verify signatures on recheck tx if !simulate && !ctx.IsReCheckTx() { - err := authsigning.VerifySignature(ctx, pubKey, signerData, sig.Data, svd.signModeHandler, tx) + anyPk, _ := codectypes.NewAnyWithValue(pubKey) + + signerData := txsigning.SignerData{ + Address: acc.GetAddress().String(), + ChainID: chainID, + AccountNumber: accNum, + Sequence: acc.GetSequence(), + PubKey: &anypb.Any{ + TypeUrl: anyPk.TypeUrl, + Value: anyPk.Value, + }, + } + decodeCtx, err := decode.NewDecoder(decode.Options{ProtoFiles: registry.MergedProtoRegistry()}) + if err != nil { + return ctx, err + } + // note: this is performance hit is temporary. Ultimately, the tx will be decoded once in BaseApp, + // but for now we need double decoding to support both SignModeHandlers. + decodedTx, err := decodeCtx.Decode(ctx.TxBytes()) + if err != nil { + return ctx, err + } + txData := txsigning.TxData{ + Body: decodedTx.Tx.Body, + AuthInfo: decodedTx.Tx.AuthInfo, + AuthInfoBytes: decodedTx.TxRaw.AuthInfoBytes, + BodyBytes: decodedTx.TxRaw.BodyBytes, + } + err = authsigning.VerifySignature(ctx, pubKey, signerData, sig.Data, svd.signModeHandler, txData) if err != nil { var errMsg string if OnlyLegacyAminoSigners(sig.Data) { diff --git a/x/auth/ante/sigverify_test.go b/x/auth/ante/sigverify_test.go index 2af60c81a8c..6309f72633f 100644 --- a/x/auth/ante/sigverify_test.go +++ b/x/auth/ante/sigverify_test.go @@ -8,6 +8,7 @@ import ( "github.com/stretchr/testify/require" storetypes "cosmossdk.io/store/types" + authsign "github.com/cosmos/cosmos-sdk/x/auth/signing" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" @@ -126,17 +127,16 @@ func TestConsumeSignatureVerificationGas(t *testing.T) { func TestSigVerification(t *testing.T) { suite := SetupTestSuite(t, true) - suite.txBankKeeper.EXPECT().DenomMetadata(suite.ctx, gomock.Any()).Return(&banktypes.QueryDenomMetadataResponse{}, nil).AnyTimes() + suite.txBankKeeper.EXPECT().DenomMetadata(gomock.Any(), gomock.Any()).Return(&banktypes.QueryDenomMetadataResponse{}, nil).AnyTimes() enabledSignModes := []signing.SignMode{signing.SignMode_SIGN_MODE_DIRECT, signing.SignMode_SIGN_MODE_TEXTUAL, signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON} // Since TEXTUAL is not enabled by default, we create a custom TxConfig // here which includes it. - txt, err := txmodule.NewTextualWithGRPCConn(suite.clientCtx) + opts, err := txmodule.NewSignModeOptionsWithMetadataQueryFn(txmodule.NewGRPCCoinMetadataQueryFn(suite.clientCtx)) require.NoError(t, err) - suite.clientCtx.TxConfig = authtx.NewTxConfigWithTextual( + suite.clientCtx.TxConfig = authtx.NewTxConfigWithOptions( codec.NewProtoCodec(suite.encCfg.InterfaceRegistry), - enabledSignModes, - txt, + opts, ) suite.txBuilder = suite.clientCtx.TxConfig.NewTxBuilder() @@ -163,15 +163,16 @@ func TestSigVerification(t *testing.T) { gasLimit := testdata.NewTestGasLimit() spkd := ante.NewSetPubKeyDecorator(suite.accountKeeper) - txt, err = txmodule.NewTextualWithBankKeeper(suite.txBankKeeper) + opts, err = txmodule.NewSignModeOptionsWithMetadataQueryFn(txmodule.NewBankKeeperCoinMetadataQueryFn(suite.txBankKeeper)) require.NoError(t, err) - anteTxConfig := authtx.NewTxConfigWithTextual( + anteTxConfig := authtx.NewTxConfigWithOptions( codec.NewProtoCodec(suite.encCfg.InterfaceRegistry), - enabledSignModes, - txt, + opts, ) svd := ante.NewSigVerificationDecorator(suite.accountKeeper, anteTxConfig.SignModeHandler()) antehandler := sdk.ChainAnteDecorators(spkd, svd) + defaultSignMode, err := authsign.APISignModeToInternal(anteTxConfig.SignModeHandler().DefaultMode()) + require.NoError(t, err) type testCase struct { name string @@ -211,7 +212,7 @@ func TestSigVerification(t *testing.T) { txSigs[0] = signing.SignatureV2{ PubKey: tc.privs[0].PubKey(), Data: &signing.SingleSignatureData{ - SignMode: suite.clientCtx.TxConfig.SignModeHandler().DefaultMode(), + SignMode: defaultSignMode, Signature: badSig, }, Sequence: tc.accSeqs[0], @@ -220,7 +221,10 @@ func TestSigVerification(t *testing.T) { tx = suite.txBuilder.GetTx() } - _, err = antehandler(suite.ctx, tx, false) + txBytes, err := suite.clientCtx.TxConfig.TxEncoder()(tx) + require.NoError(t, err) + byteCtx := suite.ctx.WithTxBytes(txBytes) + _, err = antehandler(byteCtx, tx, false) if tc.shouldErr { require.NotNil(t, err, "TestCase %d: %s did not error as expected", i, tc.name) } else { @@ -288,6 +292,10 @@ func runSigDecorators(t *testing.T, params types.Params, _ bool, privs ...crypto svd := ante.NewSigVerificationDecorator(suite.accountKeeper, suite.clientCtx.TxConfig.SignModeHandler()) antehandler := sdk.ChainAnteDecorators(spkd, svgc, svd) + txBytes, err := suite.clientCtx.TxConfig.TxEncoder()(tx) + require.NoError(t, err) + suite.ctx = suite.ctx.WithTxBytes(txBytes) + // Determine gas consumption of antehandler with default params before := suite.ctx.GasMeter().GasConsumed() ctx, err := antehandler(suite.ctx, tx, false) diff --git a/x/auth/ante/testutil_test.go b/x/auth/ante/testutil_test.go index 76cf9d39c9d..0680513cd4f 100644 --- a/x/auth/ante/testutil_test.go +++ b/x/auth/ante/testutil_test.go @@ -153,7 +153,10 @@ func (suite *AnteTestSuite) DeliverMsgs(t *testing.T, privs []cryptotypes.PrivKe tx, txErr := suite.CreateTestTx(suite.ctx, privs, accNums, accSeqs, chainID, signing.SignMode_SIGN_MODE_DIRECT) require.NoError(t, txErr) - return suite.anteHandler(suite.ctx, tx, simulate) + txBytes, err := suite.clientCtx.TxConfig.TxEncoder()(tx) + bytesCtx := suite.ctx.WithTxBytes(txBytes) + require.NoError(t, err) + return suite.anteHandler(bytesCtx, tx, simulate) } func (suite *AnteTestSuite) RunTestCase(t *testing.T, tc TestCase, args TestCaseArgs) { @@ -165,7 +168,10 @@ func (suite *AnteTestSuite) RunTestCase(t *testing.T, tc TestCase, args TestCase // ante handlers, but here we sometimes also test the tx creation // process. tx, txErr := suite.CreateTestTx(suite.ctx, args.privs, args.accNums, args.accSeqs, args.chainID, signing.SignMode_SIGN_MODE_DIRECT) - newCtx, anteErr := suite.anteHandler(suite.ctx, tx, tc.simulate) + txBytes, err := suite.clientCtx.TxConfig.TxEncoder()(tx) + require.NoError(t, err) + bytesCtx := suite.ctx.WithTxBytes(txBytes) + newCtx, anteErr := suite.anteHandler(bytesCtx, tx, tc.simulate) if tc.expPass { require.NoError(t, txErr) diff --git a/x/auth/client/cli/tx_multisign.go b/x/auth/client/cli/tx_multisign.go index 34349ec858a..1d1e0b2a5a7 100644 --- a/x/auth/client/cli/tx_multisign.go +++ b/x/auth/client/cli/tx_multisign.go @@ -7,8 +7,13 @@ import ( "github.com/spf13/cobra" "github.com/spf13/viper" + "google.golang.org/protobuf/types/known/anypb" errorsmod "cosmossdk.io/errors" + "cosmossdk.io/x/tx/decode" + txsigning "cosmossdk.io/x/tx/signing" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + "github.com/cosmos/cosmos-sdk/types/registry" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" @@ -112,6 +117,11 @@ func makeMultiSignCmd() func(cmd *cobra.Command, args []string) (err error) { txFactory = txFactory.WithAccountNumber(accnum).WithSequence(seq) } + decoder, err := decode.NewDecoder(decode.Options{ProtoFiles: registry.MergedProtoRegistry()}) + if err != nil { + return err + } + // read each signature and add it to the multisig if valid for i := 2; i < len(args); i++ { sigs, err := unmarshalSignatureJSON(clientCtx, args[i]) @@ -124,15 +134,37 @@ func makeMultiSignCmd() func(cmd *cobra.Command, args []string) (err error) { } for _, sig := range sigs { - signingData := signing.SignerData{ - Address: sdk.AccAddress(sig.PubKey.Address()).String(), + anyPk, err := codectypes.NewAnyWithValue(sig.PubKey) + if err != nil { + return err + } + txSignerData := txsigning.SignerData{ ChainID: txFactory.ChainID(), AccountNumber: txFactory.AccountNumber(), Sequence: txFactory.Sequence(), - PubKey: sig.PubKey, + Address: sdk.AccAddress(sig.PubKey.Address()).String(), + PubKey: &anypb.Any{ + TypeUrl: anyPk.TypeUrl, + Value: anyPk.Value, + }, + } + txBytes, err := txCfg.TxEncoder()(txBuilder.GetTx()) + if err != nil { + return err + } + decodedTx, err := decoder.Decode(txBytes) + if err != nil { + return err + } + txData := txsigning.TxData{ + Body: decodedTx.Tx.Body, + AuthInfo: decodedTx.Tx.AuthInfo, + AuthInfoBytes: decodedTx.TxRaw.AuthInfoBytes, + BodyBytes: decodedTx.TxRaw.BodyBytes, } - err = signing.VerifySignature(cmd.Context(), sig.PubKey, signingData, sig.Data, txCfg.SignModeHandler(), txBuilder.GetTx()) + err = signing.VerifySignature(cmd.Context(), sig.PubKey, txSignerData, sig.Data, + txCfg.SignModeHandler(), txData) if err != nil { addr, _ := sdk.AccAddressFromHexUnsafe(sig.PubKey.Address().String()) return fmt.Errorf("couldn't verify signature for address %s", addr) @@ -295,16 +327,43 @@ func makeBatchMultisignCmd() func(cmd *cobra.Command, args []string) error { } multisigPub := pubKey.(*kmultisig.LegacyAminoPubKey) multisigSig := multisig.NewMultisig(len(multisigPub.PubKeys)) - signingData := signing.SignerData{ - Address: sdk.AccAddress(pubKey.Address()).String(), + + anyPk, err := codectypes.NewAnyWithValue(multisigPub) + if err != nil { + return err + } + txSignerData := txsigning.SignerData{ ChainID: txFactory.ChainID(), AccountNumber: txFactory.AccountNumber(), Sequence: txFactory.Sequence(), - PubKey: pubKey, + Address: sdk.AccAddress(pubKey.Address()).String(), + PubKey: &anypb.Any{ + TypeUrl: anyPk.TypeUrl, + Value: anyPk.Value, + }, } + txBytes, err := txCfg.TxEncoder()(txBldr.GetTx()) + if err != nil { + return err + } + decodeCtx, err := decode.NewDecoder(decode.Options{ProtoFiles: registry.MergedProtoRegistry()}) + if err != nil { + return err + } + decodedTx, err := decodeCtx.Decode(txBytes) + if err != nil { + return err + } + txData := txsigning.TxData{ + Body: decodedTx.Tx.Body, + AuthInfo: decodedTx.Tx.AuthInfo, + AuthInfoBytes: decodedTx.TxRaw.AuthInfoBytes, + BodyBytes: decodedTx.TxRaw.BodyBytes, + } for _, sig := range signatureBatch { - err = signing.VerifySignature(cmd.Context(), sig[i].PubKey, signingData, sig[i].Data, txCfg.SignModeHandler(), txBldr.GetTx()) + err = signing.VerifySignature(cmd.Context(), sig[i].PubKey, txSignerData, sig[i].Data, + txCfg.SignModeHandler(), txData) if err != nil { return fmt.Errorf("couldn't verify signature: %w %v", err, sig) } diff --git a/x/auth/client/cli/validate_sigs.go b/x/auth/client/cli/validate_sigs.go index 6a0b8156c7f..a38283fd2d5 100644 --- a/x/auth/client/cli/validate_sigs.go +++ b/x/auth/client/cli/validate_sigs.go @@ -4,11 +4,16 @@ import ( "fmt" "github.com/spf13/cobra" + "google.golang.org/protobuf/types/known/anypb" + "cosmossdk.io/x/tx/decode" + txsigning "cosmossdk.io/x/tx/signing" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/client/tx" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/registry" authclient "github.com/cosmos/cosmos-sdk/x/auth/client" authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing" ) @@ -111,9 +116,47 @@ func printAndValidateSigs( Sequence: accSeq, PubKey: pubKey, } + anyPk, err := codectypes.NewAnyWithValue(pubKey) + if err != nil { + cmd.PrintErrf("failed to pack public key: %v", err) + return false + } + txSignerData := txsigning.SignerData{ + ChainID: signingData.ChainID, + AccountNumber: signingData.AccountNumber, + Sequence: signingData.Sequence, + Address: signingData.Address, + PubKey: &anypb.Any{ + TypeUrl: anyPk.TypeUrl, + Value: anyPk.Value, + }, + } + + txBytes, err := clientCtx.TxConfig.TxEncoder()(tx) + if err != nil { + cmd.PrintErrf("failed to encode transaction: %v", err) + return false + } + decodeCtx, err := decode.NewDecoder(decode.Options{ProtoFiles: registry.MergedProtoRegistry()}) + if err != nil { + cmd.PrintErrf("failed to create decoder: %v", err) + return false + } + decodedTx, err := decodeCtx.Decode(txBytes) + if err != nil { + cmd.PrintErrf("failed to decode transaction: %v", err) + return false + } + txData := txsigning.TxData{ + Body: decodedTx.Tx.Body, + AuthInfo: decodedTx.Tx.AuthInfo, + AuthInfoBytes: decodedTx.TxRaw.AuthInfoBytes, + BodyBytes: decodedTx.TxRaw.BodyBytes, + } - err = authsigning.VerifySignature(cmd.Context(), pubKey, signingData, sig.Data, signModeHandler, sigTx) + err = authsigning.VerifySignature(cmd.Context(), pubKey, txSignerData, sig.Data, signModeHandler, txData) if err != nil { + cmd.PrintErrf("failed to verify signature: %v", err) return false } } diff --git a/x/auth/signing/verify.go b/x/auth/signing/verify.go index 3ed7df85462..6455e60b782 100644 --- a/x/auth/signing/verify.go +++ b/x/auth/signing/verify.go @@ -4,18 +4,81 @@ import ( "context" "fmt" + "google.golang.org/protobuf/types/known/anypb" + + signingv1beta1 "cosmossdk.io/api/cosmos/tx/signing/v1beta1" + "cosmossdk.io/x/tx/decode" + txsigning "cosmossdk.io/x/tx/signing" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" "github.com/cosmos/cosmos-sdk/crypto/types/multisig" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/registry" "github.com/cosmos/cosmos-sdk/types/tx/signing" ) -// VerifySignature verifies a transaction signature contained in SignatureData abstracting over different signing modes -// and single vs multi-signatures. -func VerifySignature(ctx context.Context, pubKey cryptotypes.PubKey, signerData SignerData, sigData signing.SignatureData, handler SignModeHandler, tx sdk.Tx) error { - switch data := sigData.(type) { +// APISignModesToInternal converts a protobuf SignMode array to a signing.SignMode array. +func APISignModesToInternal(modes []signingv1beta1.SignMode) ([]signing.SignMode, error) { + internalModes := make([]signing.SignMode, len(modes)) + for i, mode := range modes { + internalMode, err := APISignModeToInternal(mode) + if err != nil { + return nil, err + } + internalModes[i] = internalMode + } + return internalModes, nil +} + +// APISignModeToInternal converts a protobuf SignMode to a signing.SignMode. +func APISignModeToInternal(mode signingv1beta1.SignMode) (signing.SignMode, error) { + switch mode { + case signingv1beta1.SignMode_SIGN_MODE_DIRECT: + return signing.SignMode_SIGN_MODE_DIRECT, nil + case signingv1beta1.SignMode_SIGN_MODE_LEGACY_AMINO_JSON: + return signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, nil + case signingv1beta1.SignMode_SIGN_MODE_TEXTUAL: + return signing.SignMode_SIGN_MODE_TEXTUAL, nil + case signingv1beta1.SignMode_SIGN_MODE_DIRECT_AUX: + return signing.SignMode_SIGN_MODE_DIRECT_AUX, nil + default: + return signing.SignMode_SIGN_MODE_UNSPECIFIED, fmt.Errorf("unsupported sign mode %s", mode) + } +} + +// internalSignModeToAPI converts a signing.SignMode to a protobuf SignMode. +func internalSignModeToAPI(mode signing.SignMode) (signingv1beta1.SignMode, error) { + switch mode { + case signing.SignMode_SIGN_MODE_DIRECT: + return signingv1beta1.SignMode_SIGN_MODE_DIRECT, nil + case signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON: + return signingv1beta1.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, nil + case signing.SignMode_SIGN_MODE_TEXTUAL: + return signingv1beta1.SignMode_SIGN_MODE_TEXTUAL, nil + case signing.SignMode_SIGN_MODE_DIRECT_AUX: + return signingv1beta1.SignMode_SIGN_MODE_DIRECT_AUX, nil + default: + return signingv1beta1.SignMode_SIGN_MODE_UNSPECIFIED, fmt.Errorf("unsupported sign mode %s", mode) + } +} + +// VerifySignature verifies a transaction signature contained in SignatureData abstracting over different signing +// modes. It differs from VerifySignature in that it uses the new txsigning.TxData interface in x/tx. +func VerifySignature( + ctx context.Context, + pubKey cryptotypes.PubKey, + signerData txsigning.SignerData, + signatureData signing.SignatureData, + handler *txsigning.HandlerMap, + txData txsigning.TxData, +) error { + switch data := signatureData.(type) { case *signing.SingleSignatureData: - signBytes, err := GetSignBytesWithContext(handler, ctx, data.SignMode, signerData, tx) + signMode, err := internalSignModeToAPI(data.SignMode) + if err != nil { + return err + } + signBytes, err := handler.GetSignBytes(ctx, signMode, signerData, txData) if err != nil { return err } @@ -30,29 +93,72 @@ func VerifySignature(ctx context.Context, pubKey cryptotypes.PubKey, signerData return fmt.Errorf("expected %T, got %T", (multisig.PubKey)(nil), pubKey) } err := multiPK.VerifyMultisignature(func(mode signing.SignMode) ([]byte, error) { - handlerWithContext, ok := handler.(SignModeHandlerWithContext) - if ok { - return handlerWithContext.GetSignBytesWithContext(ctx, mode, signerData, tx) + signMode, err := internalSignModeToAPI(mode) + if err != nil { + return nil, err } - return handler.GetSignBytes(mode, signerData, tx) + return handler.GetSignBytes(ctx, signMode, signerData, txData) }, data) if err != nil { return err } return nil default: - return fmt.Errorf("unexpected SignatureData %T", sigData) + return fmt.Errorf("unexpected SignatureData %T", signatureData) } } -// GetSignBytesWithContext gets the sign bytes from the sign mode handler. It -// checks if the sign mode handler supports SignModeHandlerWithContext, in -// which case it passes the context.Context argument. Otherwise, it fallbacks -// to GetSignBytes. -func GetSignBytesWithContext(h SignModeHandler, ctx context.Context, mode signing.SignMode, data SignerData, tx sdk.Tx) ([]byte, error) { //nolint:revive // refactor this in a future pr - hWithCtx, ok := h.(SignModeHandlerWithContext) - if ok { - return hWithCtx.GetSignBytesWithContext(ctx, mode, data, tx) +// GetSignBytesAdapter returns the sign bytes for a given transaction and sign mode. It accepts the arguments expected +// for signing in x/auth/tx and converts them to the arguments expected by the txsigning.HandlerMap, then applies +// HandlerMap.GetSignBytes to get the sign bytes. +func GetSignBytesAdapter( + ctx context.Context, + encoder sdk.TxEncoder, + handlerMap *txsigning.HandlerMap, + mode signing.SignMode, + signerData SignerData, + tx sdk.Tx, +) ([]byte, error) { + // round trip performance hit. + // could be avoided if we had a way to get the bytes from the txBuilder. + txBytes, err := encoder(tx) + if err != nil { + return nil, err + } + decodeCtx, err := decode.NewDecoder(decode.Options{ProtoFiles: registry.MergedProtoRegistry()}) + if err != nil { + return nil, err + } + decodedTx, err := decodeCtx.Decode(txBytes) + if err != nil { + return nil, err + } + txData := txsigning.TxData{ + Body: decodedTx.Tx.Body, + AuthInfo: decodedTx.Tx.AuthInfo, + AuthInfoBytes: decodedTx.TxRaw.AuthInfoBytes, + BodyBytes: decodedTx.TxRaw.BodyBytes, + } + txSignMode, err := internalSignModeToAPI(mode) + if err != nil { + return nil, err + } + + anyPk, err := codectypes.NewAnyWithValue(signerData.PubKey) + if err != nil { + return nil, err + } + + txSignerData := txsigning.SignerData{ + ChainID: signerData.ChainID, + AccountNumber: signerData.AccountNumber, + Sequence: signerData.Sequence, + Address: signerData.Address, + PubKey: &anypb.Any{ + TypeUrl: anyPk.TypeUrl, + Value: anyPk.Value, + }, } - return h.GetSignBytes(mode, data, tx) + // Generate the bytes to be signed. + return handlerMap.GetSignBytes(ctx, txSignMode, txSignerData, txData) } diff --git a/x/auth/tx/aux_test.go b/x/auth/tx/aux_test.go index 97416a9df89..90481f5767c 100644 --- a/x/auth/tx/aux_test.go +++ b/x/auth/tx/aux_test.go @@ -1,6 +1,7 @@ package tx_test import ( + "context" "testing" "github.com/stretchr/testify/require" @@ -130,17 +131,18 @@ func TestBuilderWithAux(t *testing.T) { PubKey: feepayerPk, Sequence: 15, }) - signBz, err = txConfig.SignModeHandler().GetSignBytes( - signing.SignMode_SIGN_MODE_DIRECT, - authsigning.SignerData{ - Address: feepayerAddr.String(), - ChainID: chainID, - AccountNumber: 11, - Sequence: 15, - PubKey: feepayerPk, - }, - w.GetTx(), - ) + signerData := authsigning.SignerData{ + Address: feepayerAddr.String(), + ChainID: chainID, + AccountNumber: 11, + Sequence: 15, + PubKey: feepayerPk, + } + + signBz, err = authsigning.GetSignBytesAdapter( + context.Background(), txConfig.TxEncoder(), txConfig.SignModeHandler(), signing.SignMode_SIGN_MODE_DIRECT, + signerData, w.GetTx()) + require.NoError(t, err) feepayerSig, err := feepayerPriv.Sign(signBz) require.NoError(t, err) diff --git a/x/auth/tx/config.go b/x/auth/tx/config.go index 5cb00e96907..6d89cd41ecd 100644 --- a/x/auth/tx/config.go +++ b/x/auth/tx/config.go @@ -3,17 +3,21 @@ package tx import ( "fmt" - "cosmossdk.io/x/tx/signing/textual" + "google.golang.org/protobuf/reflect/protoregistry" + + txsigning "cosmossdk.io/x/tx/signing" + "cosmossdk.io/x/tx/signing/aminojson" + "cosmossdk.io/x/tx/signing/direct" + "cosmossdk.io/x/tx/signing/directaux" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" signingtypes "github.com/cosmos/cosmos-sdk/types/tx/signing" - "github.com/cosmos/cosmos-sdk/x/auth/signing" ) type config struct { - handler signing.SignModeHandler + handler *txsigning.HandlerMap decoder sdk.TxDecoder encoder sdk.TxEncoder jsonDecoder sdk.TxDecoder @@ -27,25 +31,66 @@ type config struct { // 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). Use NewTxConfigWithTextual // to enable SIGN_MODE_TEXTUAL (for testing purposes for now). -func NewTxConfig(protoCodec codec.ProtoCodecMarshaler, enabledSignModes []signingtypes.SignMode, customSignModes ...signing.SignModeHandler) client.TxConfig { +// +// 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 +// TODO: collapse enabledSignModes and customSignModes +func NewTxConfig(protoCodec codec.ProtoCodecMarshaler, enabledSignModes []signingtypes.SignMode, + customSignModes ...txsigning.SignModeHandler, +) client.TxConfig { + typeResolver := protoregistry.GlobalTypes + protoFiles := protoCodec.InterfaceRegistry() + signersContext, err := txsigning.NewGetSignersContext(txsigning.GetSignersOptions{ProtoFiles: protoFiles}) + if err != nil { + panic(err) + } + + signModeOptions := &SignModeOptions{} for _, m := range enabledSignModes { - if m == signingtypes.SignMode_SIGN_MODE_TEXTUAL { + switch m { + case signingtypes.SignMode_SIGN_MODE_DIRECT: + signModeOptions.Direct = &direct.SignModeHandler{} + case signingtypes.SignMode_SIGN_MODE_DIRECT_AUX: + signModeOptions.DirectAux = &directaux.SignModeHandlerOptions{ + FileResolver: protoFiles, + TypeResolver: typeResolver, + SignersContext: signersContext, + } + case signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON: + aminoJSONEncoder := aminojson.NewAminoJSON() + signModeOptions.AminoJSON = &aminojson.SignModeHandlerOptions{ + FileResolver: protoFiles, + TypeResolver: typeResolver, + Encoder: &aminoJSONEncoder, + } + case signingtypes.SignMode_SIGN_MODE_TEXTUAL: panic("cannot use NewTxConfig with SIGN_MODE_TEXTUAL enabled; please use NewTxConfigWithTextual") } } - return NewTxConfigWithHandler(protoCodec, makeSignModeHandler(enabledSignModes, &textual.SignModeHandler{}, customSignModes...)) + return NewTxConfigWithHandler(protoCodec, makeSignModeHandler(*signModeOptions, customSignModes...)) +} + +func NewTxConfigWithOptions(protoCodec codec.ProtoCodecMarshaler, signModeOptions SignModeOptions, + customSignModes ...txsigning.SignModeHandler, +) client.TxConfig { + return NewTxConfigWithHandler(protoCodec, makeSignModeHandler(signModeOptions, customSignModes...)) } // 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.SignModeHandler, customSignModes ...signing.SignModeHandler) client.TxConfig { - return NewTxConfigWithHandler(protoCodec, makeSignModeHandler(enabledSignModes, textual, customSignModes...)) +// +// Deprecated: use NewTxConfigWithOptions instead. +func NewTxConfigWithTextual(protoCodec codec.ProtoCodecMarshaler, _ []signingtypes.SignMode, + signModeOptions SignModeOptions, customSignModes ...txsigning.SignModeHandler, +) client.TxConfig { + return NewTxConfigWithOptions(protoCodec, signModeOptions, customSignModes...) } -// NewTxConfig returns a new protobuf TxConfig using the provided ProtoCodec and signing handler. -func NewTxConfigWithHandler(protoCodec codec.ProtoCodecMarshaler, handler signing.SignModeHandler) client.TxConfig { +// NewTxConfigWithHandler returns a new protobuf TxConfig using the provided ProtoCodec and signing handler. +func NewTxConfigWithHandler(protoCodec codec.ProtoCodecMarshaler, handler *txsigning.HandlerMap) client.TxConfig { return &config{ handler: handler, decoder: DefaultTxDecoder(protoCodec), @@ -70,7 +115,7 @@ func (g config) WrapTxBuilder(newTx sdk.Tx) (client.TxBuilder, error) { return newBuilder, nil } -func (g config) SignModeHandler() signing.SignModeHandler { +func (g config) SignModeHandler() *txsigning.HandlerMap { return g.handler } diff --git a/x/auth/tx/config/config.go b/x/auth/tx/config/config.go index dbfa624e045..5a3ce85b32f 100644 --- a/x/auth/tx/config/config.go +++ b/x/auth/tx/config/config.go @@ -1,43 +1,54 @@ package tx import ( + "context" "fmt" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + grpcstatus "google.golang.org/grpc/status" + "google.golang.org/protobuf/reflect/protoregistry" + + bankv1beta1 "cosmossdk.io/api/cosmos/bank/v1beta1" txconfigv1 "cosmossdk.io/api/cosmos/tx/config/v1" "cosmossdk.io/core/appmodule" "cosmossdk.io/depinject" + txsigning "cosmossdk.io/x/tx/signing" + "cosmossdk.io/x/tx/signing/aminojson" + "cosmossdk.io/x/tx/signing/direct" + "cosmossdk.io/x/tx/signing/directaux" + "cosmossdk.io/x/tx/signing/textual" + "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/runtime" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/registry" "github.com/cosmos/cosmos-sdk/x/auth/ante" "github.com/cosmos/cosmos-sdk/x/auth/posthandler" - "github.com/cosmos/cosmos-sdk/x/auth/signing" "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" ) func init() { appmodule.Register(&txconfigv1.Config{}, appmodule.Provide(ProvideModule), + appmodule.Provide(ProvideSignModeOptions), ) } type ModuleInputs struct { depinject.In - Config *txconfigv1.Config ProtoCodecMarshaler codec.ProtoCodecMarshaler - - AccountKeeper ante.AccountKeeper `optional:"true"` + SignModeOptions tx.SignModeOptions // 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 ante.FeegrantKeeper `optional:"true"` - - CustomSignModeHandlers func() []signing.SignModeHandler `optional:"true"` + BankKeeper authtypes.BankKeeper `optional:"true"` + AccountKeeper ante.AccountKeeper `optional:"true"` + FeeGrantKeeper ante.FeegrantKeeper `optional:"true"` + CustomSignModeHandlers func() []txsigning.SignModeHandler `optional:"true"` } type ModuleOutputs struct { @@ -47,17 +58,22 @@ type ModuleOutputs struct { BaseAppOption runtime.BaseAppOption } -func ProvideModule(in ModuleInputs) ModuleOutputs { - textual, err := NewTextualWithBankKeeper(in.TxBankKeeper) +// ProvideSignModeOptions provides the default x/tx SignModeOptions for the SDK. +func ProvideSignModeOptions(bk BankKeeper) tx.SignModeOptions { + opts, err := NewSignModeOptionsWithMetadataQueryFn(NewBankKeeperCoinMetadataQueryFn(bk)) if err != nil { panic(err) } + return opts +} + +func ProvideModule(in ModuleInputs) ModuleOutputs { var txConfig client.TxConfig - if in.CustomSignModeHandlers == nil { - txConfig = tx.NewTxConfigWithTextual(in.ProtoCodecMarshaler, tx.DefaultSignModes, textual) - } else { - txConfig = tx.NewTxConfigWithTextual(in.ProtoCodecMarshaler, tx.DefaultSignModes, textual, in.CustomSignModeHandlers()...) + var customSignModeHandlers []txsigning.SignModeHandler + if in.CustomSignModeHandlers != nil { + customSignModeHandlers = in.CustomSignModeHandlers() } + txConfig = tx.NewTxConfigWithOptions(in.ProtoCodecMarshaler, in.SignModeOptions, customSignModeHandlers...) baseAppOption := func(app *baseapp.BaseApp) { // AnteHandlers @@ -121,3 +137,111 @@ func newAnteHandler(txConfig client.TxConfig, in ModuleInputs) (sdk.AnteHandler, return anteHandler, nil } + +// NewBankKeeperCoinMetadataQueryFn creates a new Textual struct using the given +// BankKeeper to retrieve coin metadata. +// +// Note: Once we switch to ADR-033, and keepers become ADR-033 clients to each +// other, this function could probably be deprecated in favor of +// `NewTextualWithGRPCConn`. +func NewBankKeeperCoinMetadataQueryFn(bk BankKeeper) textual.CoinMetadataQueryFn { + return func(ctx context.Context, denom string) (*bankv1beta1.Metadata, error) { + res, err := bk.DenomMetadata(ctx, &types.QueryDenomMetadataRequest{Denom: denom}) + if err != nil { + return nil, metadataExists(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 + } +} + +// NewGRPCCoinMetadataQueryFn returns a new Textual instance where the metadata +// queries are done via gRPC using the provided GRPC client connection. In the +// SDK, you can pass a client.Context as the GRPC connection. +// +// Example: +// +// clientCtx := client.GetClientContextFromCmd(cmd) +// txt := tx.NewTextualWithGRPCConn(clientCtxx) +func NewGRPCCoinMetadataQueryFn(grpcConn grpc.ClientConnInterface) textual.CoinMetadataQueryFn { + return func(ctx context.Context, denom string) (*bankv1beta1.Metadata, error) { + bankQueryClient := bankv1beta1.NewQueryClient(grpcConn) + res, err := bankQueryClient.DenomMetadata(ctx, &bankv1beta1.QueryDenomMetadataRequest{ + Denom: denom, + }) + if err != nil { + return nil, metadataExists(err) + } + + return res.Metadata, nil + } +} + +// NewSignModeOptionsWithMetadataQueryFn creates a new SignModeOptions instance +func NewSignModeOptionsWithMetadataQueryFn(fn textual.CoinMetadataQueryFn) (tx.SignModeOptions, error) { + protoFiles := registry.MergedProtoRegistry() + typeResolver := protoregistry.GlobalTypes + signersContext, err := txsigning.NewGetSignersContext(txsigning.GetSignersOptions{ProtoFiles: protoFiles}) + if err != nil { + return tx.SignModeOptions{}, err + } + + aminoJSONEncoder := aminojson.NewAminoJSON() + signModeOptions := tx.SignModeOptions{ + Direct: &direct.SignModeHandler{}, + DirectAux: &directaux.SignModeHandlerOptions{ + FileResolver: protoFiles, + TypeResolver: typeResolver, + SignersContext: signersContext, + }, + AminoJSON: &aminojson.SignModeHandlerOptions{ + FileResolver: protoFiles, + TypeResolver: typeResolver, + Encoder: &aminoJSONEncoder, + }, + Textual: &textual.SignModeOptions{ + CoinMetadataQuerier: fn, + FileResolver: protoFiles, + TypeResolver: typeResolver, + }, + } + + return signModeOptions, nil +} + +// metadataExists parses the error, and only propagates the error if it's +// different than a "not found" error. +func metadataExists(err error) error { + status, ok := grpcstatus.FromError(err) + if !ok { + return err + } + + // This means we didn't find any metadata for this denom. Returning + // empty metadata. + if status.Code() == codes.NotFound { + return nil + } + + return err +} diff --git a/x/auth/tx/config/textual.go b/x/auth/tx/config/textual.go deleted file mode 100644 index 3a93cb689d1..00000000000 --- a/x/auth/tx/config/textual.go +++ /dev/null @@ -1,107 +0,0 @@ -package tx - -import ( - "context" - - gogoproto "github.com/cosmos/gogoproto/proto" - "google.golang.org/grpc" - "google.golang.org/grpc/codes" - grpcstatus "google.golang.org/grpc/status" - - bankv1beta1 "cosmossdk.io/api/cosmos/bank/v1beta1" - "cosmossdk.io/x/tx/signing/textual" - - "github.com/cosmos/cosmos-sdk/x/bank/types" -) - -// NewTextualWithGRPCConn returns a new Textual instance where the metadata -// queries are done via gRPC using the provided GRPC client connection. In the -// SDK, you can pass a client.Context as the GRPC connection. -// -// Example: -// -// clientCtx := client.GetClientContextFromCmd(cmd) -// txt := tx.NewTextualWithGRPCConn(clientCtxx) -func NewTextualWithGRPCConn(grpcConn grpc.ClientConnInterface) (*textual.SignModeHandler, error) { - protoFiles, err := gogoproto.MergedRegistry() - if err != nil { - return nil, err - } - - return textual.NewSignModeHandler(textual.SignModeOptions{ - CoinMetadataQuerier: func(ctx context.Context, denom string) (*bankv1beta1.Metadata, error) { - bankQueryClient := bankv1beta1.NewQueryClient(grpcConn) - res, err := bankQueryClient.DenomMetadata(ctx, &bankv1beta1.QueryDenomMetadataRequest{ - Denom: denom, - }) - if err != nil { - return nil, metadataExists(err) - } - - return res.Metadata, nil - }, - FileResolver: protoFiles, - }) -} - -// NewTextualWithBankKeeper creates a new Textual struct using the given -// BankKeeper to retrieve coin metadata. -// -// Note: Once we switch to ADR-033, and keepers become ADR-033 clients to each -// other, this function could probably be deprecated in favor of -// `NewTextualWithGRPCConn`. -func NewTextualWithBankKeeper(bk BankKeeper) (*textual.SignModeHandler, error) { - protoFiles, err := gogoproto.MergedRegistry() - if err != nil { - return nil, err - } - - return textual.NewSignModeHandler(textual.SignModeOptions{ - CoinMetadataQuerier: func(ctx context.Context, denom string) (*bankv1beta1.Metadata, error) { - res, err := bk.DenomMetadata(ctx, &types.QueryDenomMetadataRequest{Denom: denom}) - if err != nil { - return nil, metadataExists(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 - }, - FileResolver: protoFiles, - }) -} - -// metadataExists parses the error, and only propagates the error if it's -// different than a "not found" error. -func metadataExists(err error) error { - status, ok := grpcstatus.FromError(err) - if !ok { - return err - } - - // This means we didn't find any metadata for this denom. Returning - // empty metadata. - if status.Code() == codes.NotFound { - return nil - } - - return err -} diff --git a/x/auth/tx/direct_test.go b/x/auth/tx/direct_test.go index 22309639656..09365541ee6 100644 --- a/x/auth/tx/direct_test.go +++ b/x/auth/tx/direct_test.go @@ -1,6 +1,7 @@ package tx import ( + "context" "fmt" "testing" @@ -64,9 +65,10 @@ func TestDirectModeHandler(t *testing.T) { require.NoError(t, err) t.Log("verify modes and default-mode") - modeHandler := txConfig.SignModeHandler() - require.Equal(t, modeHandler.DefaultMode(), signingtypes.SignMode_SIGN_MODE_DIRECT) - require.Len(t, modeHandler.Modes(), 1) + defaultSignMode, err := signing.APISignModeToInternal(txConfig.SignModeHandler().DefaultMode()) + require.NoError(t, err) + require.Equal(t, defaultSignMode, signingtypes.SignMode_SIGN_MODE_DIRECT) + require.Len(t, txConfig.SignModeHandler().SupportedModes(), 1) signingData := signing.SignerData{ Address: addr.String(), @@ -75,8 +77,9 @@ func TestDirectModeHandler(t *testing.T) { PubKey: pubkey, } - signBytes, err := modeHandler.GetSignBytes(signingtypes.SignMode_SIGN_MODE_DIRECT, signingData, txBuilder.GetTx()) - + signBytes, err := signing.GetSignBytesAdapter( + context.Background(), txConfig.TxEncoder(), txConfig.SignModeHandler(), defaultSignMode, signingData, + txBuilder.GetTx()) require.NoError(t, err) require.NotNil(t, signBytes) @@ -120,7 +123,9 @@ func TestDirectModeHandler(t *testing.T) { require.NoError(t, err) err = txBuilder.SetSignatures(sig) require.NoError(t, err) - signBytes, err = modeHandler.GetSignBytes(signingtypes.SignMode_SIGN_MODE_DIRECT, signingData, txBuilder.GetTx()) + signBytes, err = signing.GetSignBytesAdapter( + context.Background(), txConfig.TxEncoder(), txConfig.SignModeHandler(), defaultSignMode, signingData, + txBuilder.GetTx()) require.NoError(t, err) require.Equal(t, expectedSignBytes, signBytes) diff --git a/x/auth/tx/mode_handler.go b/x/auth/tx/mode_handler.go index 25a2612b49b..ff0b3440a4b 100644 --- a/x/auth/tx/mode_handler.go +++ b/x/auth/tx/mode_handler.go @@ -1,14 +1,25 @@ package tx import ( - "fmt" - + txsigning "cosmossdk.io/x/tx/signing" + "cosmossdk.io/x/tx/signing/aminojson" + "cosmossdk.io/x/tx/signing/direct" + "cosmossdk.io/x/tx/signing/directaux" "cosmossdk.io/x/tx/signing/textual" - signingtypes "github.com/cosmos/cosmos-sdk/types/tx/signing" - "github.com/cosmos/cosmos-sdk/x/auth/signing" ) +type SignModeOptions struct { + // Textual are options for SIGN_MODE_TEXTUAL + Textual *textual.SignModeOptions + // DirectAux are options for SIGN_MODE_DIRECT_AUX + DirectAux *directaux.SignModeHandlerOptions + // AminoJSON are options for SIGN_MODE_LEGACY_AMINO_JSON + AminoJSON *aminojson.SignModeHandlerOptions + // Direct is the SignModeHandler for SIGN_MODE_DIRECT since it takes options + Direct *direct.SignModeHandler +} + // DefaultSignModes are the default sign modes enabled for protobuf transactions. var DefaultSignModes = []signingtypes.SignMode{ signingtypes.SignMode_SIGN_MODE_DIRECT, @@ -24,36 +35,31 @@ var DefaultSignModes = []signingtypes.SignMode{ // 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, txt *textual.SignModeHandler, customSignModes ...signing.SignModeHandler) signing.SignModeHandler { - if len(modes) < 1 { - panic(fmt.Errorf("no sign modes enabled")) +func makeSignModeHandler( + opts SignModeOptions, + customSignModes ...txsigning.SignModeHandler, +) *txsigning.HandlerMap { + var handlers []txsigning.SignModeHandler + if opts.Direct != nil { + handlers = append(handlers, opts.Direct) } - - handlers := make([]signing.SignModeHandler, len(modes)+len(customSignModes)) - - // handle cosmos-sdk defined sign modes - for i, mode := range modes { - switch mode { - case signingtypes.SignMode_SIGN_MODE_DIRECT: - 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: - panic(fmt.Errorf("unsupported sign mode %+v", mode)) + if opts.Textual != nil { + h, err := textual.NewSignModeHandler(*opts.Textual) + if err != nil { + panic(err) } + handlers = append(handlers, h) } - - // add custom sign modes - for i, handler := range customSignModes { - handlers[i+len(modes)] = handler + if opts.DirectAux != nil { + h, err := directaux.NewSignModeHandler(*opts.DirectAux) + if err != nil { + panic(err) + } + handlers = append(handlers, h) } - - return signing.NewSignModeHandlerMap( - modes[0], - handlers, - ) + if opts.AminoJSON != nil { + handlers = append(handlers, aminojson.NewSignModeHandler(*opts.AminoJSON)) + } + handlers = append(handlers, customSignModes...) + return txsigning.NewHandlerMap(handlers...) } diff --git a/x/auth/tx/testutil/suite.go b/x/auth/tx/testutil/suite.go index 924f2366ca3..ab9ab69096d 100644 --- a/x/auth/tx/testutil/suite.go +++ b/x/auth/tx/testutil/suite.go @@ -2,9 +2,11 @@ package testutil import ( "bytes" + "context" "github.com/stretchr/testify/suite" + signingv1beta1 "cosmossdk.io/api/cosmos/tx/signing/v1beta1" "github.com/cosmos/cosmos-sdk/client" kmultisig "github.com/cosmos/cosmos-sdk/crypto/keys/multisig" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" @@ -96,17 +98,19 @@ func (s *TxConfigTestSuite) TestTxBuilderSetSignatures() { s.Require().Error(txBuilder.GetTx().ValidateBasic()) signModeHandler := s.TxConfig.SignModeHandler() - s.Require().Contains(signModeHandler.Modes(), signModeHandler.DefaultMode()) + s.Require().Contains(signModeHandler.SupportedModes(), signingv1beta1.SignMode_SIGN_MODE_DIRECT) + defaultSignMode, err := signing.APISignModeToInternal(s.TxConfig.SignModeHandler().DefaultMode()) + s.Require().NoError(err) // set SignatureV2 without actual signature bytes seq1 := uint64(2) // Arbitrary account sequence - sigData1 := &signingtypes.SingleSignatureData{SignMode: signModeHandler.DefaultMode()} + sigData1 := &signingtypes.SingleSignatureData{SignMode: defaultSignMode} sig1 := signingtypes.SignatureV2{PubKey: pubkey, Data: sigData1, Sequence: seq1} mseq := uint64(4) // Arbitrary account sequence msigData := multisig.NewMultisig(2) - multisig.AddSignature(msigData, &signingtypes.SingleSignatureData{SignMode: signModeHandler.DefaultMode()}, 0) - multisig.AddSignature(msigData, &signingtypes.SingleSignatureData{SignMode: signModeHandler.DefaultMode()}, 1) + multisig.AddSignature(msigData, &signingtypes.SingleSignatureData{SignMode: defaultSignMode}, 0) + multisig.AddSignature(msigData, &signingtypes.SingleSignatureData{SignMode: defaultSignMode}, 1) msig := signingtypes.SignatureV2{PubKey: multisigPk, Data: msigData, Sequence: mseq} // fail validation without required signers @@ -134,7 +138,8 @@ func (s *TxConfigTestSuite) TestTxBuilderSetSignatures() { Sequence: seq1, PubKey: pubkey, } - signBytes, err := signModeHandler.GetSignBytes(signModeHandler.DefaultMode(), signerData, sigTx) + signBytes, err := signing.GetSignBytesAdapter(context.Background(), s.TxConfig.TxEncoder(), + s.TxConfig.SignModeHandler(), defaultSignMode, signerData, sigTx) s.Require().NoError(err) sigBz, err := privKey.Sign(signBytes) s.Require().NoError(err) @@ -146,7 +151,8 @@ func (s *TxConfigTestSuite) TestTxBuilderSetSignatures() { Sequence: mseq, PubKey: multisigPk, } - mSignBytes, err := signModeHandler.GetSignBytes(signModeHandler.DefaultMode(), signerData, sigTx) + mSignBytes, err := signing.GetSignBytesAdapter(context.Background(), s.TxConfig.TxEncoder(), + s.TxConfig.SignModeHandler(), defaultSignMode, signerData, sigTx) s.Require().NoError(err) mSigBz1, err := privKey.Sign(mSignBytes) s.Require().NoError(err) @@ -154,10 +160,10 @@ func (s *TxConfigTestSuite) TestTxBuilderSetSignatures() { s.Require().NoError(err) msigData = multisig.NewMultisig(2) multisig.AddSignature(msigData, &signingtypes.SingleSignatureData{ - SignMode: signModeHandler.DefaultMode(), Signature: mSigBz1, + SignMode: defaultSignMode, Signature: mSigBz1, }, 0) multisig.AddSignature(msigData, &signingtypes.SingleSignatureData{ - SignMode: signModeHandler.DefaultMode(), Signature: mSigBz2, + SignMode: defaultSignMode, Signature: mSigBz2, }, 0) // set signature diff --git a/x/authz/client/cli/tx_test.go b/x/authz/client/cli/tx_test.go index 55563ec827a..b3b57706a90 100644 --- a/x/authz/client/cli/tx_test.go +++ b/x/authz/client/cli/tx_test.go @@ -6,12 +6,14 @@ import ( "testing" "time" - sdkmath "cosmossdk.io/math" abci "github.com/cometbft/cometbft/abci/types" rpcclientmock "github.com/cometbft/cometbft/rpc/client/mock" "github.com/cosmos/gogoproto/proto" "github.com/stretchr/testify/suite" + sdkmath "cosmossdk.io/math" + + _ "cosmossdk.io/api/cosmos/authz/v1beta1" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" addresscodec "github.com/cosmos/cosmos-sdk/codec/address" diff --git a/x/group/client/cli/tx_test.go b/x/group/client/cli/tx_test.go index 4a2b6dd4909..20f0fe2024b 100644 --- a/x/group/client/cli/tx_test.go +++ b/x/group/client/cli/tx_test.go @@ -7,11 +7,14 @@ import ( "io" "testing" - sdkmath "cosmossdk.io/math" abci "github.com/cometbft/cometbft/abci/types" rpcclientmock "github.com/cometbft/cometbft/rpc/client/mock" "github.com/stretchr/testify/suite" + // without this import amino json encoding will fail when resolving any types + _ "cosmossdk.io/api/cosmos/group/v1" + sdkmath "cosmossdk.io/math" + "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/codec/address"