diff --git a/CHANGELOG.md b/CHANGELOG.md index 92e9156574f3..ae290136e41b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,7 +37,8 @@ Ref: https://keepachangelog.com/en/1.0.0/ ## [Unreleased] * [\#9205](https://github.com/cosmos/cosmos-sdk/pull/9205) Improve readability in `abci` handleQueryP2P -## Features +### Features + * [\#8965](https://github.com/cosmos/cosmos-sdk/pull/8965) cosmos reflection now provides more information on the application such as: deliverable msgs, sdk.Config info etc (still in alpha stage). * [\#8559](https://github.com/cosmos/cosmos-sdk/pull/8559) Added Protobuf compatible secp256r1 ECDSA signatures. * [\#8786](https://github.com/cosmos/cosmos-sdk/pull/8786) Enabled secp256r1 in x/auth. @@ -48,6 +49,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ * (x/staking) [\#9214](https://github.com/cosmos/cosmos-sdk/pull/9214) Added `new_shares` attribute inside `EventTypeDelegate` event. ### Client Breaking Changes + * [\#8363](https://github.com/cosmos/cosmos-sdk/pull/8363) Addresses no longer have a fixed 20-byte length. From the SDK modules' point of view, any 1-255 bytes-long byte array is a valid address. * [\#8346](https://github.com/cosmos/cosmos-sdk/pull/8346) All CLI `tx` commands generate ServiceMsgs by default. Graceful Amino support has been added to ServiceMsgs to support signing legacy Msgs. * (crypto/ed25519) [\#8690] Adopt zip1215 ed2559 verification rules. @@ -59,6 +61,10 @@ Ref: https://keepachangelog.com/en/1.0.0/ * CLI: removed `--text` flag from `show-node-id` command; the text format for public keys is not used any more - instead we use ProtoJSON. * (types) [\#9079](https://github.com/cosmos/cosmos-sdk/issues/9079) Add `AddAmount`/`SubAmount` methods to `sdk.Coin`. * [\#8628](https://github.com/cosmos/cosmos-sdk/issues/8628) Commands no longer print outputs using `stderr` by default +* [\#9139](https://github.com/cosmos/cosmos-sdk/pull/9139) Querying events: + * via `ServiceMsg` TypeURLs (e.g. `message.action='/cosmos.bank.v1beta1.Msg/Send'`) does not work anymore, + * via legacy `msg.Type()` (e.g. `message.action='send'`) is being deprecated, new `Msg`s won't emit these events. + * Please use concrete `Msg` TypeURLs instead (e.g. `message.action='/cosmos.bank.v1beta1.MsgSend'`). ### API Breaking Changes @@ -92,6 +98,10 @@ Ref: https://keepachangelog.com/en/1.0.0/ * `codec.JSONMarshaler` → `codec.JSONCodec` * Removed `BinaryBare` suffix from `BinaryCodec` methods (`MarshalBinaryBare`, `UnmarshalBinaryBare`, ...) * Removed `Binary` infix from `BinaryCodec` methods (`MarshalBinaryLengthPrefixed`, `UnmarshalBinaryLengthPrefixed`, ...) +* [\#9139](https://github.com/cosmos/cosmos-sdk/pull/9139) `ServiceMsg` TypeURLs (e.g. `/cosmos.bank.v1beta1.Msg/Send`) have been removed, as they don't comply to the Probobuf `Any` spec. Please use `Msg` type TypeURLs (e.g. `/cosmos.bank.v1beta1.MsgSend`). This has multiple consequences: + * The `sdk.ServiceMsg` struct has been removed. + * `sdk.Msg` now only contains `ValidateBasic` and `GetSigners` methods. The remaining methods `GetSignBytes`, `Route` and `Type` are moved to `legacytx.LegacyMsg`. + * The `RegisterCustomTypeURL` function and the `cosmos.base.v1beta1.ServiceMsg` interface have been removed from the interface registry. diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index 5ec243ba91b8..6c66e6e008e3 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -19,6 +19,7 @@ import ( "github.com/cosmos/cosmos-sdk/store/rootmulti" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/x/auth/legacy/legacytx" ) const ( @@ -703,37 +704,39 @@ func (app *BaseApp) runMsgs(ctx sdk.Context, msgs []sdk.Msg, mode runTxMode) (*s } var ( - msgEvents sdk.Events - msgResult *sdk.Result - msgFqName string - err error + msgResult *sdk.Result + eventMsgName string // name to use as value in event `message.action` + err error ) - if svcMsg, ok := msg.(sdk.ServiceMsg); ok { - msgFqName = svcMsg.MethodName - handler := app.msgServiceRouter.Handler(msgFqName) - if handler == nil { - return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized message service method: %s; message index: %d", msgFqName, i) - } - msgResult, err = handler(ctx, svcMsg.Request) - } else { + if handler := app.msgServiceRouter.Handler(msg); handler != nil { + // ADR 031 request type routing + msgResult, err = handler(ctx, msg) + eventMsgName = sdk.MsgTypeURL(msg) + } else if legacyMsg, ok := msg.(legacytx.LegacyMsg); ok { // legacy sdk.Msg routing - msgRoute := msg.Route() - msgFqName = msg.Type() + // Assuming that the app developer has migrated all their Msgs to + // proto messages and has registered all `Msg services`, then this + // path should never be called, because all those Msgs should be + // registered within the `msgServiceRouter` already. + msgRoute := legacyMsg.Route() + eventMsgName = legacyMsg.Type() handler := app.router.Route(ctx, msgRoute) if handler == nil { return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized message route: %s; message index: %d", msgRoute, i) } msgResult, err = handler(ctx, msg) + } else { + return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "can't route message %+v", msg) } if err != nil { return nil, sdkerrors.Wrapf(err, "failed to execute message; message index: %d", i) } - msgEvents = sdk.Events{ - sdk.NewEvent(sdk.EventTypeMessage, sdk.NewAttribute(sdk.AttributeKeyAction, msgFqName)), + msgEvents := sdk.Events{ + sdk.NewEvent(sdk.EventTypeMessage, sdk.NewAttribute(sdk.AttributeKeyAction, eventMsgName)), } msgEvents = msgEvents.AppendEvents(msgResult.GetEvents()) @@ -743,7 +746,7 @@ func (app *BaseApp) runMsgs(ctx sdk.Context, msgs []sdk.Msg, mode runTxMode) (*s // separate each result. events = events.AppendEvents(msgEvents) - txMsgData.Data = append(txMsgData.Data, &sdk.MsgData{MsgType: msg.Type(), Data: msgResult.Data}) + txMsgData.Data = append(txMsgData.Data, &sdk.MsgData{MsgType: sdk.MsgTypeURL(msg), Data: msgResult.Data}) msgLogs = append(msgLogs, sdk.NewABCIMessageLog(uint32(i), msgResult.Log, msgEvents)) } diff --git a/baseapp/msg_service_router.go b/baseapp/msg_service_router.go index ea2ed4b4eb6a..086bcbd267c5 100644 --- a/baseapp/msg_service_router.go +++ b/baseapp/msg_service_router.go @@ -29,12 +29,17 @@ func NewMsgServiceRouter() *MsgServiceRouter { } // MsgServiceHandler defines a function type which handles Msg service message. -type MsgServiceHandler = func(ctx sdk.Context, req sdk.MsgRequest) (*sdk.Result, error) +type MsgServiceHandler = func(ctx sdk.Context, req sdk.Msg) (*sdk.Result, error) -// Handler returns the MsgServiceHandler for a given query route path or nil +// Handler returns the MsgServiceHandler for a given msg or nil if not found. +func (msr *MsgServiceRouter) Handler(msg sdk.Msg) MsgServiceHandler { + return msr.routes[sdk.MsgTypeURL(msg)] +} + +// HandlerbyTypeURL returns the MsgServiceHandler for a given query route path or nil // if not found. -func (msr *MsgServiceRouter) Handler(methodName string) MsgServiceHandler { - return msr.routes[methodName] +func (msr *MsgServiceRouter) HandlerbyTypeURL(typeURL string) MsgServiceHandler { + return msr.routes[typeURL] } // RegisterService implements the gRPC Server.RegisterService method. sd is a gRPC @@ -50,20 +55,38 @@ func (msr *MsgServiceRouter) RegisterService(sd *grpc.ServiceDesc, handler inter fqMethod := fmt.Sprintf("/%s/%s", sd.ServiceName, method.MethodName) methodHandler := method.Handler + var requestTypeName string + + // NOTE: This is how we pull the concrete request type for each handler for registering in the InterfaceRegistry. + // This approach is maybe a bit hacky, but less hacky than reflecting on the handler object itself. + // We use a no-op interceptor to avoid actually calling into the handler itself. + _, _ = methodHandler(nil, context.Background(), func(i interface{}) error { + msg, ok := i.(sdk.Msg) + if !ok { + // We panic here because there is no other alternative and the app cannot be initialized correctly + // this should only happen if there is a problem with code generation in which case the app won't + // work correctly anyway. + panic(fmt.Errorf("can't register request type %T for service method %s", i, fqMethod)) + } + + requestTypeName = sdk.MsgTypeURL(msg) + return nil + }, noopInterceptor) + // Check that the service Msg fully-qualified method name has already // been registered (via RegisterInterfaces). If the user registers a // service without registering according service Msg type, there might be // some unexpected behavior down the road. Since we can't return an error // (`Server.RegisterService` interface restriction) we panic (at startup). - serviceMsg, err := msr.interfaceRegistry.Resolve(fqMethod) - if err != nil || serviceMsg == nil { + reqType, err := msr.interfaceRegistry.Resolve(requestTypeName) + if err != nil || reqType == nil { panic( fmt.Errorf( "type_url %s has not been registered yet. "+ "Before calling RegisterService, you must register all interfaces by calling the `RegisterInterfaces` "+ "method on module.BasicManager. Each module should call `msgservice.RegisterMsgServiceDesc` inside its "+ "`RegisterInterfaces` method with the `_Msg_serviceDesc` generated by proto-gen", - fqMethod, + requestTypeName, ), ) } @@ -72,7 +95,7 @@ func (msr *MsgServiceRouter) RegisterService(sd *grpc.ServiceDesc, handler inter // registered more than once, then we should error. Since we can't // return an error (`Server.RegisterService` interface restriction) we // panic (at startup). - _, found := msr.routes[fqMethod] + _, found := msr.routes[requestTypeName] if found { panic( fmt.Errorf( @@ -83,7 +106,7 @@ func (msr *MsgServiceRouter) RegisterService(sd *grpc.ServiceDesc, handler inter ) } - msr.routes[fqMethod] = func(ctx sdk.Context, req sdk.MsgRequest) (*sdk.Result, error) { + msr.routes[requestTypeName] = func(ctx sdk.Context, req sdk.Msg) (*sdk.Result, error) { ctx = ctx.WithEventManager(sdk.NewEventManager()) interceptor := func(goCtx context.Context, _ interface{}, _ *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { goCtx = context.WithValue(goCtx, sdk.SdkContextKey, ctx) @@ -112,3 +135,6 @@ func (msr *MsgServiceRouter) SetInterfaceRegistry(interfaceRegistry codectypes.I } func noopDecoder(_ interface{}) error { return nil } +func noopInterceptor(_ context.Context, _ interface{}, _ *grpc.UnaryServerInfo, _ grpc.UnaryHandler) (interface{}, error) { + return nil, nil +} diff --git a/baseapp/msg_service_router_test.go b/baseapp/msg_service_router_test.go index 34f9c080277e..d599d0cbe47a 100644 --- a/baseapp/msg_service_router_test.go +++ b/baseapp/msg_service_router_test.go @@ -80,11 +80,11 @@ func TestMsgService(t *testing.T) { ) _ = app.BeginBlock(abci.RequestBeginBlock{Header: tmproto.Header{Height: 1}}) - msg := testdata.NewServiceMsgCreateDog(&testdata.MsgCreateDog{Dog: &testdata.Dog{Name: "Spot"}}) + msg := testdata.MsgCreateDog{Dog: &testdata.Dog{Name: "Spot"}} txBuilder := encCfg.TxConfig.NewTxBuilder() txBuilder.SetFeeAmount(testdata.NewTestFeeAmount()) txBuilder.SetGasLimit(testdata.NewTestGasLimit()) - err := txBuilder.SetMsgs(msg) + err := txBuilder.SetMsgs(&msg) require.NoError(t, err) // First round: we gather all the signer infos. We use the "set empty diff --git a/client/tx/legacy_test.go b/client/tx/legacy_test.go index 5dcab771c495..e3ac1e630ed1 100644 --- a/client/tx/legacy_test.go +++ b/client/tx/legacy_test.go @@ -13,7 +13,6 @@ import ( "github.com/cosmos/cosmos-sdk/simapp/params" "github.com/cosmos/cosmos-sdk/testutil/testdata" "github.com/cosmos/cosmos-sdk/types" - sdk "github.com/cosmos/cosmos-sdk/types" signing2 "github.com/cosmos/cosmos-sdk/types/tx/signing" "github.com/cosmos/cosmos-sdk/x/auth/legacy/legacytx" "github.com/cosmos/cosmos-sdk/x/auth/signing" @@ -39,10 +38,7 @@ var ( }, } msg0 = banktypes.NewMsgSend(addr1, addr2, types.NewCoins(types.NewInt64Coin("wack", 1))) - msg1 = sdk.ServiceMsg{ - MethodName: "/cosmos.bank.v1beta1.Msg/Send", - Request: banktypes.NewMsgSend(addr1, addr2, types.NewCoins(types.NewInt64Coin("wack", 2))), - } + msg1 = banktypes.NewMsgSend(addr1, addr2, types.NewCoins(types.NewInt64Coin("wack", 2))) ) func buildTestTx(t *testing.T, builder client.TxBuilder) { @@ -88,7 +84,7 @@ func (s *TestSuite) TestCopyTx() { s.Require().Equal(sigsV2_1, sigsV2_2) s.Require().Equal(protoBuilder.GetTx().GetSigners(), protoBuilder2.GetTx().GetSigners()) s.Require().Equal(protoBuilder.GetTx().GetMsgs()[0], protoBuilder2.GetTx().GetMsgs()[0]) - s.Require().Equal(protoBuilder.GetTx().GetMsgs()[1].(sdk.ServiceMsg).Request, protoBuilder2.GetTx().GetMsgs()[1]) // We lose the "ServiceMsg" information + s.Require().Equal(protoBuilder.GetTx().GetMsgs()[1], protoBuilder2.GetTx().GetMsgs()[1]) // amino -> proto -> amino aminoBuilder = s.aminoCfg.NewTxBuilder() @@ -120,7 +116,7 @@ func (s *TestSuite) TestConvertTxToStdTx() { s.Require().Equal(gas, stdTx.Fee.Gas) s.Require().Equal(fee, stdTx.Fee.Amount) s.Require().Equal(msg0, stdTx.Msgs[0]) - s.Require().Equal(msg1.Request, stdTx.Msgs[1]) + s.Require().Equal(msg1, stdTx.Msgs[1]) s.Require().Equal(timeoutHeight, stdTx.TimeoutHeight) s.Require().Equal(sig.PubKey, stdTx.Signatures[0].PubKey) s.Require().Equal(sig.Data.(*signing2.SingleSignatureData).Signature, stdTx.Signatures[0].Signature) @@ -140,7 +136,7 @@ func (s *TestSuite) TestConvertTxToStdTx() { s.Require().Equal(gas, stdTx.Fee.Gas) s.Require().Equal(fee, stdTx.Fee.Amount) s.Require().Equal(msg0, stdTx.Msgs[0]) - s.Require().Equal(msg1.Request, stdTx.Msgs[1]) + s.Require().Equal(msg1, stdTx.Msgs[1]) s.Require().Equal(timeoutHeight, stdTx.TimeoutHeight) s.Require().Empty(stdTx.Signatures) diff --git a/codec/types/any.go b/codec/types/any.go index 14087efa8fd6..07c8de98c81e 100644 --- a/codec/types/any.go +++ b/codec/types/any.go @@ -64,20 +64,14 @@ func NewAnyWithValue(v proto.Message) (*Any, error) { if v == nil { return nil, sdkerrors.Wrap(sdkerrors.ErrPackAny, "Expecting non nil value to create a new Any") } - return NewAnyWithCustomTypeURL(v, "/"+proto.MessageName(v)) -} -// NewAnyWithCustomTypeURL same as NewAnyWithValue, but sets a custom type url, instead -// using the one from proto.Message. -// NOTE: This functions should be only used for types with additional logic bundled -// into the protobuf Any serialization. For simple marshaling you should use NewAnyWithValue. -func NewAnyWithCustomTypeURL(v proto.Message, typeURL string) (*Any, error) { bz, err := proto.Marshal(v) if err != nil { return nil, err } + return &Any{ - TypeUrl: typeURL, + TypeUrl: "/" + proto.MessageName(v), Value: bz, cachedValue: v, }, nil diff --git a/codec/types/any_test.go b/codec/types/any_test.go index cea3e0444efb..b9ddbe72ec39 100644 --- a/codec/types/any_test.go +++ b/codec/types/any_test.go @@ -23,8 +23,6 @@ func (eom *errOnMarshal) XXX_Marshal(b []byte, deterministic bool) ([]byte, erro return nil, errAlways } -const fauxURL = "/anyhere" - var eom = &errOnMarshal{} // Ensure that returning an error doesn't suddenly allocate and waste bytes. @@ -32,7 +30,7 @@ var eom = &errOnMarshal{} func TestNewAnyWithCustomTypeURLWithErrorNoAllocation(t *testing.T) { var ms1, ms2 runtime.MemStats runtime.ReadMemStats(&ms1) - any, err := types.NewAnyWithCustomTypeURL(eom, fauxURL) + any, err := types.NewAnyWithValue(eom) runtime.ReadMemStats(&ms2) // Ensure that no fresh allocation was made. if diff := ms2.HeapAlloc - ms1.HeapAlloc; diff > 0 { @@ -52,7 +50,7 @@ func BenchmarkNewAnyWithCustomTypeURLWithErrorReturned(b *testing.B) { b.ResetTimer() b.ReportAllocs() for i := 0; i < b.N; i++ { - any, err := types.NewAnyWithCustomTypeURL(eom, fauxURL) + any, err := types.NewAnyWithValue(eom) if err == nil { b.Fatal("err wasn't returned") } diff --git a/codec/types/interface_registry.go b/codec/types/interface_registry.go index 0f9eb760beca..5d7e72e890c0 100644 --- a/codec/types/interface_registry.go +++ b/codec/types/interface_registry.go @@ -46,17 +46,6 @@ type InterfaceRegistry interface { // registry.RegisterImplementations((*sdk.Msg)(nil), &MsgSend{}, &MsgMultiSend{}) RegisterImplementations(iface interface{}, impls ...proto.Message) - // RegisterCustomTypeURL allows a protobuf message to be registered as a - // google.protobuf.Any with a custom typeURL (besides its own canonical - // typeURL). iface should be an interface as type, as in RegisterInterface - // and RegisterImplementations. - // - // Ex: - // This will allow us to pack service methods in Any's using the full method name - // as the type URL and the request body as the value, and allow us to unpack - // such packed methods using the normal UnpackAny method for the interface iface. - RegisterCustomTypeURL(iface interface{}, typeURL string, impl proto.Message) - // ListAllInterfaces list the type URLs of all registered interfaces. ListAllInterfaces() []string diff --git a/codec/types/types_test.go b/codec/types/types_test.go index 43f85375508e..24c83b4eb5f9 100644 --- a/codec/types/types_test.go +++ b/codec/types/types_test.go @@ -1,18 +1,13 @@ package types_test import ( - "context" - "fmt" "strings" "testing" - "github.com/gogo/protobuf/grpc" "github.com/gogo/protobuf/jsonpb" "github.com/gogo/protobuf/proto" "github.com/stretchr/testify/require" - grpc2 "google.golang.org/grpc" - "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/codec/types" "github.com/cosmos/cosmos-sdk/testutil/testdata" ) @@ -185,60 +180,3 @@ func TestAny_ProtoJSON(t *testing.T) { require.NoError(t, err) require.Equal(t, spot, ha2.Animal.GetCachedValue()) } - -// this instance of grpc.ClientConn is used to test packing service method -// requests into Any's -type testAnyPackClient struct { - any types.Any - interfaceRegistry types.InterfaceRegistry -} - -var _ grpc.ClientConn = &testAnyPackClient{} - -func (t *testAnyPackClient) Invoke(_ context.Context, method string, args, _ interface{}, _ ...grpc2.CallOption) error { - reqMsg, ok := args.(proto.Message) - if !ok { - return fmt.Errorf("can't proto marshal %T", args) - } - - // registry the method request type with the interface registry - t.interfaceRegistry.RegisterCustomTypeURL((*interface{})(nil), method, reqMsg) - - bz, err := proto.Marshal(reqMsg) - if err != nil { - return err - } - - t.any.TypeUrl = method - t.any.Value = bz - - return nil -} - -func (t *testAnyPackClient) NewStream(context.Context, *grpc2.StreamDesc, string, ...grpc2.CallOption) (grpc2.ClientStream, error) { - return nil, fmt.Errorf("not supported") -} - -func TestAny_ServiceRequestProtoJSON(t *testing.T) { - interfaceRegistry := types.NewInterfaceRegistry() - anyPacker := &testAnyPackClient{interfaceRegistry: interfaceRegistry} - dogMsgClient := testdata.NewMsgClient(anyPacker) - _, err := dogMsgClient.CreateDog(context.Background(), &testdata.MsgCreateDog{Dog: &testdata.Dog{ - Name: "spot", - }}) - require.NoError(t, err) - - // marshal JSON - cdc := codec.NewProtoCodec(interfaceRegistry) - bz, err := cdc.MarshalJSON(&anyPacker.any) - require.NoError(t, err) - require.Equal(t, - `{"@type":"/testdata.Msg/CreateDog","dog":{"size":"","name":"spot"}}`, - string(bz)) - - // unmarshal JSON - var any2 types.Any - err = cdc.UnmarshalJSON(bz, &any2) - require.NoError(t, err) - require.Equal(t, anyPacker.any, any2) -} diff --git a/contrib/rosetta/configuration/transfer.ros b/contrib/rosetta/configuration/transfer.ros index 74ebd2ddf50c..201a8ab7c449 100644 --- a/contrib/rosetta/configuration/transfer.ros +++ b/contrib/rosetta/configuration/transfer.ros @@ -83,7 +83,7 @@ transfer(3){ transfer.operations = [ { "operation_identifier":{"index":0}, - "type":"cosmos.bank.v1beta1.MsgSend", + "type":"/cosmos.bank.v1beta1.MsgSend", "account":{{sender.account_identifier}}, "metadata": { "amount": [ diff --git a/contrib/rosetta/node/data.tar.gz b/contrib/rosetta/node/data.tar.gz index d96715778251..3c37adcc162f 100644 Binary files a/contrib/rosetta/node/data.tar.gz and b/contrib/rosetta/node/data.tar.gz differ diff --git a/docs/architecture/adr-031-msg-service.md b/docs/architecture/adr-031-msg-service.md index a36d86c4312f..a4ff9cb54ac9 100644 --- a/docs/architecture/adr-031-msg-service.md +++ b/docs/architecture/adr-031-msg-service.md @@ -3,6 +3,7 @@ ## Changelog - 2020-10-05: Initial Draft +- 2021-04-21: Remove `ServiceMsg`s to follow Protobuf `Any`'s spec, see [#9063](https://github.com/cosmos/cosmos-sdk/issues/9063). ## Status @@ -96,71 +97,28 @@ On the client side, developers could take advantage of this by creating RPC impl logic. Protobuf libraries that use asynchronous callbacks, like [protobuf.js](https://github.com/protobufjs/protobuf.js#using-services) could use this to register callbacks for specific messages even for transactions that include multiple `Msg`s. -For backwards compatibility, existing `Msg` types should be used as the request parameter -for `service` definitions. Newer `Msg` types which only support `service` definitions -should use the more canonical `Msg...Request` names. +Each `Msg` service method should have exactly one request parameter: its corresponding `Msg` type. For example, the `Msg` service method `/cosmos.gov.v1beta1.Msg/SubmitProposal` above has exactly one request parameter, namely the `Msg` type `/cosmos.gov.v1beta1.MsgSubmitProposal`. It is important the reader understands clearly the nomenclature difference between a `Msg` service (a Protobuf service) and a `Msg` type (a Protobuf message), and the differences in their fully-qualified name. -### Encoding - -Currently, we are encoding `Msg`s as `Any` in `Tx`s which involves packing the -binary-encoded `Msg` with its type URL. +This convention has been decided over the more canonical `Msg...Request` names mainly for backwards compatibility, but also for better readability in `TxBody.messages` (see [Encoding section](#encoding) below): transactions containing `/cosmos.gov.MsgSubmitProposal` read better than those containing `/cosmos.gov.v1beta1.MsgSubmitProposalRequest`. -The type URL for `MsgSubmitProposal` based on the proto3 spec is `/cosmos.gov.MsgSubmitProposal`. +One consequence of this convention is that each `Msg` type can be the request parameter of only one `Msg` service method. However, we consider this limitation a good practice in explicitness. -The fully-qualified name for the `SubmitProposal` service method above (also -based on the proto3 and gRPC specs) is `/cosmos.gov.Msg/SubmitProposal` which varies -by a single `/` character. The generated `.pb.go` files for protobuf `service`s -include names of this form and any compliant protobuf/gRPC code generator will -generate the same name. +### Encoding -In order to encode service methods in transactions, we encode them as `Any`s in -the same `TxBody.messages` field as other `Msg`s. We simply set `Any.type_url` -to the full-qualified method name (ex. `/cosmos.gov.Msg/SubmitProposal`) and -set `Any.value` to the protobuf encoding of the request message -(`MsgSubmitProposal` in this case). +Encoding of transactions generated with `Msg` services do not differ from current Protobuf transaction encoding as defined in [ADR-020](./adr-020-protobuf-transaction-encoding.md). We are encoding `Msg` types (which are exactly `Msg` service methods' request parameters) as `Any` in `Tx`s which involves packing the +binary-encoded `Msg` with its type URL. ### Decoding -When decoding, `TxBody.UnpackInterfaces` will need a special case -to detect if `Any` type URLs match the service method format (ex. `/cosmos.gov.Msg/SubmitProposal`) -by checking for two `/` characters. Messages that are method names plus request parameters -instead of a normal `Any` messages will get unpacked into the `ServiceMsg` struct: - -```go -type ServiceMsg struct { - // MethodName is the fully-qualified service name - MethodName string - // Request is the request payload - Request MsgRequest -} -``` +Since `Msg` types are packed into `Any`, decoding transactions messages are done by unpacking `Any`s into `Msg` types. For more information, please refer to [ADR-020](./adr-020-protobuf-transaction-encoding.md#transactions). ### Routing -In the future, `service` definitions may become the primary method for defining -`Msg`s. As a starting point, we need to integrate with the SDK's existing routing -and `Msg` interface. - -To do this, `ServiceMsg` implements the `sdk.Msg` interface and its handler does the -actual method routing, allowing this feature to be added incrementally on top of -existing functionality. - -### `MsgRequest` interface - -All request messages will need to implement the `MsgRequest` interface which is a -simplified version of `Msg`, without `Route()`, `Type()` and `GetSignBytes()` which -are no longer needed: +We propose to add a `msg_service_router` in BaseApp. This router is a key/value map which maps `Msg` types' `type_url`s to their corresponding `Msg` service method handler. Since there is a 1-to-1 mapping between `Msg` types and `Msg` service method, the `msg_service_router` has exactly one entry per `Msg` service method. -```go -type MsgRequest interface { - proto.Message - ValidateBasic() error - GetSigners() []AccAddress -} -``` +When a transaction is processed by BaseApp (in CheckTx or in DeliverTx), its `TxBody.messages` are decoded as `Msg`s. Each `Msg`'s `type_url` is matched against an entry in the `msg_service_router`, and the respective `Msg` service method handler is called. -`ServiceMsg` will forward its `ValidateBasic` and `GetSigners` methods to the `MsgRequest` -methods. +For backward compatability, the old handlers are not removed yet. If BaseApp receives a legacy `Msg` with no correspoding entry in the `msg_service_router`, it will be routed via its legacy `Route()` method into the legacy handler. ### Module Configuration @@ -192,8 +150,8 @@ The `RegisterServices` method and the `Configurator` interface are intended to evolve to satisfy the use cases discussed in [\#7093](https://github.com/cosmos/cosmos-sdk/issues/7093) and [\#7122](https://github.com/cosmos/cosmos-sdk/issues/7421). -When `Msg` services are registered, the framework _should_ verify that all `Msg...Request` types -implement the `MsgRequest` interface described above and throw an error during initialization rather +When `Msg` services are registered, the framework _should_ verify that all `Msg` types +implement the `sdk.Msg` interface and throw an error during initialization rather than later when transactions are processed. ### `Msg` Service Implementation @@ -211,8 +169,7 @@ func (k Keeper) SubmitProposal(goCtx context.Context, params *types.MsgSubmitPro } ``` -The `sdk.Context` should have an `EventManager` already attached by the `ServiceMsg` -router. +The `sdk.Context` should have an `EventManager` already attached by BaseApp's `msg_service_router`. Separate handler definition is no longer needed with this approach. @@ -232,8 +189,6 @@ Finally, closing a module to client API opens desirable OCAP patterns discussed - dramatically reduces and simplifies the code ### Cons -- supporting both this and the current concrete `Msg` type approach simultaneously could be confusing -(we could choose to deprecate the current approach) - using `service` definitions outside the context of gRPC could be confusing (but doesn’t violate the proto3 spec) diff --git a/server/grpc/reflection/v2alpha1/reflection.go b/server/grpc/reflection/v2alpha1/reflection.go index 728d54ad4bbc..e18295c90b33 100644 --- a/server/grpc/reflection/v2alpha1/reflection.go +++ b/server/grpc/reflection/v2alpha1/reflection.go @@ -169,12 +169,12 @@ func newTxDescriptor(ir codectypes.InterfaceRegistry) (*TxDescriptor, error) { return nil, fmt.Errorf("unable to get *tx.Tx protobuf name") } // get msgs - svcMsgImplementers := ir.ListImplementations(sdk.ServiceMsgInterfaceProtoName) + sdkMsgImplementers := ir.ListImplementations(sdk.MsgInterfaceProtoName) - msgsDesc := make([]*MsgDescriptor, 0, len(svcMsgImplementers)) + msgsDesc := make([]*MsgDescriptor, 0, len(sdkMsgImplementers)) // process sdk.ServiceMsg - for _, svcMsg := range svcMsgImplementers { + for _, svcMsg := range sdkMsgImplementers { resolved, err := ir.Resolve(svcMsg) if err != nil { return nil, fmt.Errorf("unable to resolve sdk.ServiceMsg %s: %w", svcMsg, err) diff --git a/server/grpc/server_test.go b/server/grpc/server_test.go index c7bd93982b18..e3bd71fe4feb 100644 --- a/server/grpc/server_test.go +++ b/server/grpc/server_test.go @@ -16,7 +16,9 @@ import ( "google.golang.org/grpc/metadata" rpb "google.golang.org/grpc/reflection/grpc_reflection_v1alpha" + "github.com/cosmos/cosmos-sdk/client" reflectionv1 "github.com/cosmos/cosmos-sdk/client/grpc/reflection" + clienttx "github.com/cosmos/cosmos-sdk/client/tx" reflectionv2 "github.com/cosmos/cosmos-sdk/server/grpc/reflection/v2alpha1" "github.com/cosmos/cosmos-sdk/testutil/network" "github.com/cosmos/cosmos-sdk/testutil/testdata" @@ -24,7 +26,8 @@ import ( grpctypes "github.com/cosmos/cosmos-sdk/types/grpc" "github.com/cosmos/cosmos-sdk/types/tx" txtypes "github.com/cosmos/cosmos-sdk/types/tx" - banktestutil "github.com/cosmos/cosmos-sdk/x/bank/client/testutil" + "github.com/cosmos/cosmos-sdk/types/tx/signing" + authclient "github.com/cosmos/cosmos-sdk/x/auth/client" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" ) @@ -95,6 +98,7 @@ func (s *IntegrationTestSuite) TestGRPCServer_BankBalance() { &banktypes.QueryBalanceRequest{Address: val0.Address.String(), Denom: denom}, grpc.Header(&header), ) + s.Require().NoError(err) blockHeight = header.Get(grpctypes.GRPCBlockHeightHeader) s.Require().NotEmpty(blockHeight[0]) // blockHeight is []string, first element is block height. } @@ -161,9 +165,20 @@ func (s *IntegrationTestSuite) TestGRPCServer_GetTxsEvent() { func (s *IntegrationTestSuite) TestGRPCServer_BroadcastTx() { val0 := s.network.Validators[0] - grpcRes, err := banktestutil.LegacyGRPCProtoMsgSend(val0.ClientCtx, - val0.Moniker, val0.Address, val0.Address, - sdk.Coins{sdk.NewInt64Coin(s.cfg.BondDenom, 10)}, sdk.Coins{sdk.NewInt64Coin(s.cfg.BondDenom, 10)}, + txBuilder := s.mkTxBuilder() + + txBytes, err := val0.ClientCtx.TxConfig.TxEncoder()(txBuilder.GetTx()) + s.Require().NoError(err) + + // Broadcast the tx via gRPC. + queryClient := txtypes.NewServiceClient(s.conn) + + grpcRes, err := queryClient.BroadcastTx( + context.Background(), + &txtypes.BroadcastTxRequest{ + Mode: txtypes.BroadcastMode_BROADCAST_MODE_SYNC, + TxBytes: txBytes, + }, ) s.Require().NoError(err) s.Require().Equal(uint32(0), grpcRes.TxResponse.Code) @@ -174,7 +189,6 @@ func (s *IntegrationTestSuite) TestGRPCServer_BroadcastTx() { // See issue https://github.com/cosmos/cosmos-sdk/issues/7662. func (s *IntegrationTestSuite) TestGRPCServerInvalidHeaderHeights() { t := s.T() - val0 := s.network.Validators[0] // We should reject connections with invalid block heights off the bat. invalidHeightStrs := []struct { @@ -189,13 +203,7 @@ func (s *IntegrationTestSuite) TestGRPCServerInvalidHeaderHeights() { } for _, tt := range invalidHeightStrs { t.Run(tt.value, func(t *testing.T) { - conn, err := grpc.Dial( - val0.AppConfig.GRPC.Address, - grpc.WithInsecure(), // Or else we get "no transport security set" - ) - defer conn.Close() - - testClient := testdata.NewQueryClient(conn) + testClient := testdata.NewQueryClient(s.conn) ctx := metadata.AppendToOutgoingContext(context.Background(), grpctypes.GRPCBlockHeightHeader, tt.value) testRes, err := testClient.Echo(ctx, &testdata.EchoRequest{Message: "hello"}) require.Error(t, err) @@ -205,6 +213,40 @@ func (s *IntegrationTestSuite) TestGRPCServerInvalidHeaderHeights() { } } +// mkTxBuilder creates a TxBuilder containing a signed tx from validator 0. +func (s IntegrationTestSuite) mkTxBuilder() client.TxBuilder { + val := s.network.Validators[0] + s.Require().NoError(s.network.WaitForNextBlock()) + + // prepare txBuilder with msg + txBuilder := val.ClientCtx.TxConfig.NewTxBuilder() + feeAmount := sdk.Coins{sdk.NewInt64Coin(s.cfg.BondDenom, 10)} + gasLimit := testdata.NewTestGasLimit() + s.Require().NoError( + txBuilder.SetMsgs(&banktypes.MsgSend{ + FromAddress: val.Address.String(), + ToAddress: val.Address.String(), + Amount: sdk.Coins{sdk.NewInt64Coin(s.cfg.BondDenom, 10)}, + }), + ) + txBuilder.SetFeeAmount(feeAmount) + txBuilder.SetGasLimit(gasLimit) + txBuilder.SetMemo("foobar") + + // setup txFactory + txFactory := clienttx.Factory{}. + WithChainID(val.ClientCtx.ChainID). + WithKeybase(val.ClientCtx.Keyring). + WithTxConfig(val.ClientCtx.TxConfig). + WithSignMode(signing.SignMode_SIGN_MODE_DIRECT) + + // Sign Tx. + err := authclient.SignTx(txFactory, val.ClientCtx, val.Moniker, txBuilder, false, true) + s.Require().NoError(err) + + return txBuilder +} + func TestIntegrationTestSuite(t *testing.T) { suite.Run(t, new(IntegrationTestSuite)) } diff --git a/server/rosetta/client_online.go b/server/rosetta/client_online.go index bd122b4069d7..ac3db862222e 100644 --- a/server/rosetta/client_online.go +++ b/server/rosetta/client_online.go @@ -6,7 +6,6 @@ import ( "encoding/hex" "fmt" "strconv" - "strings" "time" "github.com/cosmos/cosmos-sdk/version" @@ -71,7 +70,7 @@ func NewClient(cfg *Config) (*Client, error) { } if _, ok := resolvedMsg.(sdk.Msg); ok { - supportedOperations = append(supportedOperations, strings.TrimLeft(ii, "/")) + supportedOperations = append(supportedOperations, ii) } } diff --git a/server/rosetta/converter.go b/server/rosetta/converter.go index e9e5db559e64..7d2609a67387 100644 --- a/server/rosetta/converter.go +++ b/server/rosetta/converter.go @@ -18,7 +18,6 @@ import ( "github.com/cosmos/cosmos-sdk/types/tx/signing" rosettatypes "github.com/coinbase/rosetta-sdk-go/types" - "github.com/gogo/protobuf/proto" crgerrs "github.com/tendermint/cosmos-rosetta-gateway/errors" abci "github.com/tendermint/tendermint/abci/types" tmtypes "github.com/tendermint/tendermint/types" @@ -147,7 +146,7 @@ func (c converter) UnsignedTx(ops []*rosettatypes.Operation) (tx authsigning.Tx, for i := 0; i < len(ops); i++ { op := ops[i] - protoMessage, err := c.ir.Resolve("/" + op.Type) + protoMessage, err := c.ir.Resolve(op.Type) if err != nil { return nil, crgerrs.WrapError(crgerrs.ErrBadArgument, "operation not found: "+op.Type) } @@ -241,31 +240,7 @@ func (c converter) Meta(msg sdk.Msg) (meta map[string]interface{}, err error) { // with the message proto name as type, and the raw fields // as metadata func (c converter) Ops(status string, msg sdk.Msg) ([]*rosettatypes.Operation, error) { - opName := proto.MessageName(msg) - // in case proto does not recognize the message name - // then we should try to cast it to service msg, to - // check if it was wrapped or not, in case the cast - // from sdk.ServiceMsg to sdk.Msg fails, then a - // codec error is returned - if opName == "" { - unwrappedMsg, ok := msg.(sdk.ServiceMsg) - if !ok { - return nil, crgerrs.WrapError(crgerrs.ErrCodec, fmt.Sprintf("unrecognized message type: %T", msg)) - } - - msg, ok = unwrappedMsg.Request.(sdk.Msg) - if !ok { - return nil, crgerrs.WrapError( - crgerrs.ErrCodec, - fmt.Sprintf("unable to cast %T to sdk.Msg, method: %s", unwrappedMsg.Request, unwrappedMsg.MethodName), - ) - } - - opName = proto.MessageName(msg) - if opName == "" { - return nil, crgerrs.WrapError(crgerrs.ErrCodec, fmt.Sprintf("unrecognized message type: %T", msg)) - } - } + opName := sdk.MsgTypeURL(msg) meta, err := c.Meta(msg) if err != nil { diff --git a/testutil/testdata/tx.go b/testutil/testdata/tx.go index 4da80c9e4e8f..653400ffb67c 100644 --- a/testutil/testdata/tx.go +++ b/testutil/testdata/tx.go @@ -77,14 +77,7 @@ func (msg *TestMsg) GetSigners() []sdk.AccAddress { } func (msg *TestMsg) ValidateBasic() error { return nil } -var _ sdk.MsgRequest = &MsgCreateDog{} +var _ sdk.Msg = &MsgCreateDog{} func (msg *MsgCreateDog) GetSigners() []sdk.AccAddress { return []sdk.AccAddress{} } func (msg *MsgCreateDog) ValidateBasic() error { return nil } - -func NewServiceMsgCreateDog(msg *MsgCreateDog) sdk.Msg { - return sdk.ServiceMsg{ - MethodName: "/testdata.Msg/CreateDog", - Request: msg, - } -} diff --git a/types/codec.go b/types/codec.go index 8123fc7d51a4..69202d488fc6 100644 --- a/types/codec.go +++ b/types/codec.go @@ -8,8 +8,6 @@ import ( const ( // MsgInterfaceProtoName defines the protobuf name of the cosmos Msg interface MsgInterfaceProtoName = "cosmos.base.v1beta1.Msg" - // ServiceMsgInterfaceProtoName defines the protobuf name of the cosmos MsgRequest interface - ServiceMsgInterfaceProtoName = "cosmos.base.v1beta1.ServiceMsg" ) // RegisterLegacyAminoCodec registers the sdk message type. @@ -21,7 +19,4 @@ func RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { // RegisterInterfaces registers the sdk message type. func RegisterInterfaces(registry types.InterfaceRegistry) { registry.RegisterInterface(MsgInterfaceProtoName, (*Msg)(nil)) - // the interface name for MsgRequest is ServiceMsg because this is most useful for clients - // to understand - it will be the way for clients to introspect on available Msg service methods - registry.RegisterInterface(ServiceMsgInterfaceProtoName, (*MsgRequest)(nil)) } diff --git a/types/msgservice/msg_service.go b/types/msgservice/msg_service.go index ddffed943e8a..382913590cad 100644 --- a/types/msgservice/msg_service.go +++ b/types/msgservice/msg_service.go @@ -3,9 +3,7 @@ package msgservice import ( "context" "fmt" - "strings" - "github.com/gogo/protobuf/proto" "google.golang.org/grpc" codectypes "github.com/cosmos/cosmos-sdk/codec/types" @@ -24,7 +22,7 @@ func RegisterMsgServiceDesc(registry codectypes.InterfaceRegistry, sd *grpc.Serv // This approach is maybe a bit hacky, but less hacky than reflecting on the handler object itself. // We use a no-op interceptor to avoid actually calling into the handler itself. _, _ = methodHandler(nil, context.Background(), func(i interface{}) error { - msg, ok := i.(proto.Message) + msg, ok := i.(sdk.Msg) if !ok { // We panic here because there is no other alternative and the app cannot be initialized correctly // this should only happen if there is a problem with code generation in which case the app won't @@ -32,7 +30,8 @@ func RegisterMsgServiceDesc(registry codectypes.InterfaceRegistry, sd *grpc.Serv panic(fmt.Errorf("can't register request type %T for service method %s", i, fqMethod)) } - registry.RegisterCustomTypeURL((*sdk.MsgRequest)(nil), fqMethod, msg) + registry.RegisterImplementations((*sdk.Msg)(nil), msg) + return nil }, noopInterceptor) @@ -43,9 +42,3 @@ func RegisterMsgServiceDesc(registry codectypes.InterfaceRegistry, sd *grpc.Serv func noopInterceptor(_ context.Context, _ interface{}, _ *grpc.UnaryServerInfo, _ grpc.UnaryHandler) (interface{}, error) { return nil, nil } - -// IsServiceMsg checks if a type URL corresponds to a service method name, -// i.e. /cosmos.bank.Msg/Send vs /cosmos.bank.MsgSend -func IsServiceMsg(typeURL string) bool { - return strings.Count(typeURL, "/") >= 2 -} diff --git a/types/msgservice/service_msg_client.go b/types/msgservice/service_msg_client.go index de3be89094f8..b77997dba7fd 100644 --- a/types/msgservice/service_msg_client.go +++ b/types/msgservice/service_msg_client.go @@ -20,10 +20,10 @@ type ServiceMsgClientConn struct { } // Invoke implements the grpc ClientConn.Invoke method -func (t *ServiceMsgClientConn) Invoke(_ context.Context, method string, args, _ interface{}, _ ...grpc.CallOption) error { - req, ok := args.(sdk.MsgRequest) +func (t *ServiceMsgClientConn) Invoke(_ context.Context, _ string, args, _ interface{}, _ ...grpc.CallOption) error { + req, ok := args.(sdk.Msg) if !ok { - return fmt.Errorf("%T should implement %T", args, (*sdk.MsgRequest)(nil)) + return fmt.Errorf("%T should implement %T", args, (*sdk.Msg)(nil)) } err := req.ValidateBasic() @@ -31,10 +31,7 @@ func (t *ServiceMsgClientConn) Invoke(_ context.Context, method string, args, _ return err } - t.msgs = append(t.msgs, sdk.ServiceMsg{ - MethodName: method, - Request: req, - }) + t.msgs = append(t.msgs, req) return nil } diff --git a/types/service_msg.go b/types/service_msg.go deleted file mode 100644 index ee6cede2eb16..000000000000 --- a/types/service_msg.go +++ /dev/null @@ -1,70 +0,0 @@ -package types - -import ( - "fmt" - - "github.com/gogo/protobuf/proto" -) - -// MsgRequest is the interface a transaction message, defined as a proto -// service method, must fulfill. -type MsgRequest interface { - proto.Message - // ValidateBasic does a simple validation check that - // doesn't require access to any other information. - ValidateBasic() error - // Signers returns the addrs of signers that must sign. - // CONTRACT: All signatures must be present to be valid. - // CONTRACT: Returns addrs in some deterministic order. - GetSigners() []AccAddress -} - -// ServiceMsg is the struct into which an Any whose typeUrl matches a service -// method format (ex. `/cosmos.gov.v1beta1.Msg/SubmitProposal`) unpacks. -type ServiceMsg struct { - // MethodName is the fully-qualified service method name. - MethodName string - // Request is the request payload. - Request MsgRequest -} - -var _ Msg = ServiceMsg{} - -func (msg ServiceMsg) ProtoMessage() {} -func (msg ServiceMsg) Reset() {} -func (msg ServiceMsg) String() string { return "ServiceMsg" } - -// Route implements Msg.Route method. -func (msg ServiceMsg) Route() string { - return msg.MethodName -} - -// ValidateBasic implements Msg.ValidateBasic method. -func (msg ServiceMsg) ValidateBasic() error { - return msg.Request.ValidateBasic() -} - -// GetSignBytes implements Msg.GetSignBytes method. -func (msg ServiceMsg) GetSignBytes() []byte { - // Here, we're gracefully supporting Amino JSON for service - // Msgs. - // ref: https://github.com/cosmos/cosmos-sdk/issues/8346 - // If `msg` is a service Msg, then we cast its `Request` to a sdk.Msg - // and call GetSignBytes on the `Request`. - msgRequest, ok := msg.Request.(Msg) - if !ok { - panic(fmt.Errorf("cannot convert ServiceMsg request to sdk.Msg, got %T", msgRequest)) - } - - return msgRequest.GetSignBytes() -} - -// GetSigners implements Msg.GetSigners method. -func (msg ServiceMsg) GetSigners() []AccAddress { - return msg.Request.GetSigners() -} - -// Type implements Msg.Type method. -func (msg ServiceMsg) Type() string { - return msg.MethodName -} diff --git a/types/simulation/types.go b/types/simulation/types.go index e2a77c11baf3..89e5c813772a 100644 --- a/types/simulation/types.go +++ b/types/simulation/types.go @@ -2,14 +2,13 @@ package simulation import ( "encoding/json" - "fmt" "math/rand" - "reflect" "time" "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth/legacy/legacytx" ) type WeightedProposalContent interface { @@ -78,16 +77,14 @@ func NewOperationMsgBasic(route, name, comment string, ok bool, msg []byte) Oper // NewOperationMsg - create a new operation message from sdk.Msg func NewOperationMsg(msg sdk.Msg, ok bool, comment string, cdc *codec.ProtoCodec) OperationMsg { - if reflect.TypeOf(msg) == reflect.TypeOf(sdk.ServiceMsg{}) { - srvMsg, ok := msg.(sdk.ServiceMsg) - if !ok { - panic(fmt.Sprintf("Expecting %T to implement sdk.ServiceMsg", msg)) - } - bz := cdc.MustMarshalJSON(srvMsg.Request) - - return NewOperationMsgBasic(srvMsg.MethodName, srvMsg.MethodName, comment, ok, bz) + if legacyMsg, okType := msg.(legacytx.LegacyMsg); okType { + return NewOperationMsgBasic(legacyMsg.Route(), legacyMsg.Type(), comment, ok, legacyMsg.GetSignBytes()) } - return NewOperationMsgBasic(msg.Route(), msg.Type(), comment, ok, msg.GetSignBytes()) + + bz := cdc.MustMarshalJSON(msg) + + return NewOperationMsgBasic(sdk.MsgTypeURL(msg), sdk.MsgTypeURL(msg), comment, ok, bz) + } // NoOpMsg - create a no-operation message diff --git a/types/tx/types.go b/types/tx/types.go index 66fbb193ad96..84ce81edcbf8 100644 --- a/types/tx/types.go +++ b/types/tx/types.go @@ -7,7 +7,6 @@ import ( cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - "github.com/cosmos/cosmos-sdk/types/msgservice" ) // MaxGasWanted defines the max gas allowed. @@ -26,20 +25,11 @@ func (t *Tx) GetMsgs() []sdk.Msg { anys := t.Body.Messages res := make([]sdk.Msg, len(anys)) for i, any := range anys { - var msg sdk.Msg - if msgservice.IsServiceMsg(any.TypeUrl) { - req := any.GetCachedValue() - if req == nil { - panic("Any cached value is nil. Transaction messages must be correctly packed Any values.") - } - msg = sdk.ServiceMsg{ - MethodName: any.TypeUrl, - Request: any.GetCachedValue().(sdk.MsgRequest), - } - } else { - msg = any.GetCachedValue().(sdk.Msg) + cached := any.GetCachedValue() + if cached == nil { + panic("Any cached value is nil. Transaction messages must be correctly packed Any values.") } - res[i] = msg + res[i] = cached.(sdk.Msg) } return res } @@ -181,20 +171,10 @@ func (t *Tx) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error { // UnpackInterfaces implements the UnpackInterfaceMessages.UnpackInterfaces method func (m *TxBody) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error { for _, any := range m.Messages { - // If the any's typeUrl contains 2 slashes, then we unpack the any into - // a ServiceMsg struct as per ADR-031. - if msgservice.IsServiceMsg(any.TypeUrl) { - var req sdk.MsgRequest - err := unpacker.UnpackAny(any, &req) - if err != nil { - return err - } - } else { - var msg sdk.Msg - err := unpacker.UnpackAny(any, &msg) - if err != nil { - return err - } + var msg sdk.Msg + err := unpacker.UnpackAny(any, &msg) + if err != nil { + return err } } diff --git a/types/tx_msg.go b/types/tx_msg.go index b8a602d88c05..d7f15e83f078 100644 --- a/types/tx_msg.go +++ b/types/tx_msg.go @@ -1,6 +1,8 @@ package types import ( + fmt "fmt" + "github.com/gogo/protobuf/proto" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" @@ -11,21 +13,10 @@ type ( Msg interface { proto.Message - // Return the message type. - // Must be alphanumeric or empty. - Route() string - - // Returns a human-readable string for the message, intended for utilization - // within tags - Type() string - // ValidateBasic does a simple validation check that // doesn't require access to any other information. ValidateBasic() error - // Get the canonical byte representation of the Msg. - GetSignBytes() []byte - // Signers returns the addrs of signers that must sign. // CONTRACT: All signatures must be present to be valid. // CONTRACT: Returns addrs in some deterministic order. @@ -85,3 +76,8 @@ type TxDecoder func(txBytes []byte) (Tx, error) // TxEncoder marshals transaction to bytes type TxEncoder func(tx Tx) ([]byte, error) + +// MsgTypeURL returns the TypeURL of a `sdk.Msg`. +func MsgTypeURL(msg Msg) string { + return fmt.Sprintf("/%s", proto.MessageName(msg)) +} diff --git a/x/auth/client/testutil/suite.go b/x/auth/client/testutil/suite.go index 4c75d2b411e9..5e449e1f6aee 100644 --- a/x/auth/client/testutil/suite.go +++ b/x/auth/client/testutil/suite.go @@ -251,19 +251,7 @@ func (s *IntegrationTestSuite) TestCLIQueryTxCmd() { sendTokens := sdk.NewInt64Coin(s.cfg.BondDenom, 10) - // Send coins, try both with legacy Msg and with Msg service. - // Legacy proto Msg. - legacyTxRes, err := bankcli.LegacyGRPCProtoMsgSend( - val.ClientCtx, val.Moniker, - val.Address, - account2.GetAddress(), - sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))), - sdk.NewCoins(sendTokens), - ) - s.Require().NoError(err) - s.Require().NoError(s.network.WaitForNextBlock()) - - // Service Msg. + // Send coins. out, err := s.createBankMsg( val, account2.GetAddress(), sdk.NewCoins(sendTokens), @@ -292,16 +280,10 @@ func (s *IntegrationTestSuite) TestCLIQueryTxCmd() { "", }, { - "happy case (legacy Msg)", - []string{legacyTxRes.TxResponse.TxHash, fmt.Sprintf("--%s=json", tmcli.OutputFlag)}, - false, - "", - }, - { - "happy case (service Msg)", + "happy case", []string{txRes.TxHash, fmt.Sprintf("--%s=json", tmcli.OutputFlag)}, false, - "/cosmos.bank.v1beta1.Msg/Send", + "/cosmos.bank.v1beta1.MsgSend", }, } diff --git a/x/auth/legacy/legacytx/stdsign.go b/x/auth/legacy/legacytx/stdsign.go index 0f352db26e16..d6b9212f12a3 100644 --- a/x/auth/legacy/legacytx/stdsign.go +++ b/x/auth/legacy/legacytx/stdsign.go @@ -16,6 +16,24 @@ import ( "github.com/cosmos/cosmos-sdk/types/tx/signing" ) +// LegacyMsg defines the old interface a message must fulfill, containing +// Amino signing method and legacy router info. +// Deprecated: Please use `Msg` instead. +type LegacyMsg interface { + sdk.Msg + + // Get the canonical byte representation of the Msg. + GetSignBytes() []byte + + // Return the message type. + // Must be alphanumeric or empty. + Route() string + + // Returns a human-readable string for the message, intended for utilization + // within tags + Type() string +} + // StdSignDoc is replay-prevention structure. // It includes the result of msg.GetSignBytes(), // as well as the ChainID (prevent cross chain replay) @@ -38,7 +56,7 @@ func StdSignBytes(chainID string, accnum, sequence, timeout uint64, fee StdFee, // If msg is a legacy Msg, then GetSignBytes is implemented. // If msg is a ServiceMsg, then GetSignBytes has graceful support of // calling GetSignBytes from its underlying Msg. - msgsBytes = append(msgsBytes, json.RawMessage(msg.GetSignBytes())) + msgsBytes = append(msgsBytes, json.RawMessage(msg.(LegacyMsg).GetSignBytes())) } bz, err := legacy.Cdc.MarshalJSON(StdSignDoc{ diff --git a/x/auth/legacy/legacytx/stdtx_builder.go b/x/auth/legacy/legacytx/stdtx_builder.go index 02ae449618ee..7e2e1c604438 100644 --- a/x/auth/legacy/legacytx/stdtx_builder.go +++ b/x/auth/legacy/legacytx/stdtx_builder.go @@ -29,25 +29,7 @@ func (s *StdTxBuilder) GetTx() authsigning.Tx { // SetMsgs implements TxBuilder.SetMsgs func (s *StdTxBuilder) SetMsgs(msgs ...sdk.Msg) error { - stdTxMsgs := make([]sdk.Msg, len(msgs)) - - for i, msg := range msgs { - switch msg := msg.(type) { - case sdk.ServiceMsg: - // Since ServiceMsg isn't registered with amino, we unpack msg.Request - // into a Msg so that it's handled gracefully for the legacy - // GET /txs/{hash} and /txs endpoints. - sdkMsg, ok := msg.Request.(sdk.Msg) - if !ok { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "Expecting %T at %d to implement sdk.Msg", msg.Request, i) - } - stdTxMsgs[i] = sdkMsg - default: - // legacy sdk.Msg - stdTxMsgs[i] = msg - } - } - s.Msgs = stdTxMsgs + s.Msgs = msgs return nil } diff --git a/x/auth/tx/builder.go b/x/auth/tx/builder.go index 31f4fdf8eca2..32eacd0137f7 100644 --- a/x/auth/tx/builder.go +++ b/x/auth/tx/builder.go @@ -204,12 +204,7 @@ func (w *wrapper) SetMsgs(msgs ...sdk.Msg) error { for i, msg := range msgs { var err error - switch msg := msg.(type) { - case sdk.ServiceMsg: - anys[i], err = codectypes.NewAnyWithCustomTypeURL(msg.Request, msg.MethodName) - default: - anys[i], err = codectypes.NewAnyWithValue(msg) - } + anys[i], err = codectypes.NewAnyWithValue(msg) if err != nil { return err } diff --git a/x/auth/tx/service_test.go b/x/auth/tx/service_test.go index 68c474facc36..98b2fbcbe677 100644 --- a/x/auth/tx/service_test.go +++ b/x/auth/tx/service_test.go @@ -32,6 +32,8 @@ import ( banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" ) +var bankMsgSendEventAction = fmt.Sprintf("message.action='%s'", sdk.MsgTypeURL(&banktypes.MsgSend{})) + type IntegrationTestSuite struct { suite.Suite @@ -192,7 +194,7 @@ func (s IntegrationTestSuite) TestGetTxEvents_GRPC() { { "request with order-by", &tx.GetTxsEventRequest{ - Events: []string{"message.action='/cosmos.bank.v1beta1.Msg/Send'"}, + Events: []string{bankMsgSendEventAction}, OrderBy: tx.OrderBy_ORDER_BY_ASC, }, false, "", @@ -200,14 +202,14 @@ func (s IntegrationTestSuite) TestGetTxEvents_GRPC() { { "without pagination", &tx.GetTxsEventRequest{ - Events: []string{"message.action='/cosmos.bank.v1beta1.Msg/Send'"}, + Events: []string{bankMsgSendEventAction}, }, false, "", }, { "with pagination", &tx.GetTxsEventRequest{ - Events: []string{"message.action='/cosmos.bank.v1beta1.Msg/Send'"}, + Events: []string{bankMsgSendEventAction}, Pagination: &query.PageRequest{ CountTotal: false, Offset: 0, @@ -219,7 +221,7 @@ func (s IntegrationTestSuite) TestGetTxEvents_GRPC() { { "with multi events", &tx.GetTxsEventRequest{ - Events: []string{"message.action='/cosmos.bank.v1beta1.Msg/Send'", "message.module='bank'"}, + Events: []string{bankMsgSendEventAction, "message.module='bank'"}, }, false, "", }, @@ -262,43 +264,43 @@ func (s IntegrationTestSuite) TestGetTxEvents_GRPCGateway() { }, { "without pagination", - fmt.Sprintf("%s/cosmos/tx/v1beta1/txs?events=%s", val.APIAddress, "message.action='/cosmos.bank.v1beta1.Msg/Send'"), + fmt.Sprintf("%s/cosmos/tx/v1beta1/txs?events=%s", val.APIAddress, bankMsgSendEventAction), false, "", }, { "with pagination", - fmt.Sprintf("%s/cosmos/tx/v1beta1/txs?events=%s&pagination.offset=%d&pagination.limit=%d", val.APIAddress, "message.action='/cosmos.bank.v1beta1.Msg/Send'", 0, 10), + fmt.Sprintf("%s/cosmos/tx/v1beta1/txs?events=%s&pagination.offset=%d&pagination.limit=%d", val.APIAddress, bankMsgSendEventAction, 0, 10), false, "", }, { "valid request: order by asc", - fmt.Sprintf("%s/cosmos/tx/v1beta1/txs?events=%s&events=%s&order_by=ORDER_BY_ASC", val.APIAddress, "message.action='/cosmos.bank.v1beta1.Msg/Send'", "message.module='bank'"), + fmt.Sprintf("%s/cosmos/tx/v1beta1/txs?events=%s&events=%s&order_by=ORDER_BY_ASC", val.APIAddress, bankMsgSendEventAction, "message.module='bank'"), false, "", }, { "valid request: order by desc", - fmt.Sprintf("%s/cosmos/tx/v1beta1/txs?events=%s&events=%s&order_by=ORDER_BY_DESC", val.APIAddress, "message.action='/cosmos.bank.v1beta1.Msg/Send'", "message.module='bank'"), + fmt.Sprintf("%s/cosmos/tx/v1beta1/txs?events=%s&events=%s&order_by=ORDER_BY_DESC", val.APIAddress, bankMsgSendEventAction, "message.module='bank'"), false, "", }, { "invalid request: invalid order by", - fmt.Sprintf("%s/cosmos/tx/v1beta1/txs?events=%s&events=%s&order_by=invalid_order", val.APIAddress, "message.action='/cosmos.bank.v1beta1.Msg/Send'", "message.module='bank'"), + fmt.Sprintf("%s/cosmos/tx/v1beta1/txs?events=%s&events=%s&order_by=invalid_order", val.APIAddress, bankMsgSendEventAction, "message.module='bank'"), true, "is not a valid tx.OrderBy", }, { "expect pass with multiple-events", - fmt.Sprintf("%s/cosmos/tx/v1beta1/txs?events=%s&events=%s", val.APIAddress, "message.action='/cosmos.bank.v1beta1.Msg/Send'", "message.module='bank'"), + fmt.Sprintf("%s/cosmos/tx/v1beta1/txs?events=%s&events=%s", val.APIAddress, bankMsgSendEventAction, "message.module='bank'"), false, "", }, { "expect pass with escape event", - fmt.Sprintf("%s/cosmos/tx/v1beta1/txs?events=%s", val.APIAddress, "message.action%3D'%2Fcosmos.bank.v1beta1.Msg%2FSend'"), + fmt.Sprintf("%s/cosmos/tx/v1beta1/txs?events=%s", val.APIAddress, "message.action%3D'/cosmos.bank.v1beta1.MsgSend'"), false, "", }, @@ -584,6 +586,7 @@ func (s IntegrationTestSuite) mkTxBuilder() client.TxBuilder { ) txBuilder.SetFeeAmount(feeAmount) txBuilder.SetGasLimit(gasLimit) + txBuilder.SetMemo("foobar") // setup txFactory txFactory := clienttx.Factory{}. diff --git a/x/authz/client/cli/tx.go b/x/authz/client/cli/tx.go index 1b74e120f043..7af67ecda20a 100644 --- a/x/authz/client/cli/tx.go +++ b/x/authz/client/cli/tx.go @@ -60,7 +60,7 @@ func NewCmdGrantAuthorization() *cobra.Command { Examples: $ %s tx %s grant cosmos1skjw.. send %s --spend-limit=1000stake --from=cosmos1skl.. - $ %s tx %s grant cosmos1skjw.. generic --msg-type=/cosmos.gov.v1beta1.Msg/Vote --from=cosmos1sk.. + $ %s tx %s grant cosmos1skjw.. generic --msg-type=/cosmos.gov.v1beta1.MsgVote --from=cosmos1sk.. `, version.AppName, types.ModuleName, bank.SendAuthorization{}.MethodName(), version.AppName, types.ModuleName), ), Args: cobra.ExactArgs(2), @@ -254,17 +254,7 @@ Example: if err != nil { return err } - msgs := theTx.GetMsgs() - serviceMsgs := make([]sdk.ServiceMsg, len(msgs)) - for i, msg := range msgs { - srvMsg, ok := msg.(sdk.ServiceMsg) - if !ok { - return fmt.Errorf("tx contains %T which is not a sdk.ServiceMsg", msg) - } - serviceMsgs[i] = srvMsg - } - - msg := types.NewMsgExecAuthorized(grantee, serviceMsgs) + msg := types.NewMsgExecAuthorized(grantee, theTx.GetMsgs()) svcMsgClientConn := &msgservice.ServiceMsgClientConn{} msgClient := types.NewMsgClient(svcMsgClientConn) _, err = msgClient.ExecAuthorized(context.Background(), &msg) diff --git a/x/authz/client/rest/grpc_query_test.go b/x/authz/client/rest/grpc_query_test.go index 676af3915b01..a94c65d6366f 100644 --- a/x/authz/client/rest/grpc_query_test.go +++ b/x/authz/client/rest/grpc_query_test.go @@ -20,6 +20,7 @@ import ( types "github.com/cosmos/cosmos-sdk/x/authz/types" banktestutil "github.com/cosmos/cosmos-sdk/x/bank/client/testutil" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" ) type IntegrationTestSuite struct { @@ -30,7 +31,7 @@ type IntegrationTestSuite struct { } var typeMsgSend = banktypes.SendAuthorization{}.MethodName() -var typeMsgVote = "/cosmos.gov.v1beta1.Msg/Vote" +var typeMsgVote = sdk.MsgTypeURL(&govtypes.MsgVote{}) func (s *IntegrationTestSuite) SetupSuite() { s.T().Log("setting up integration test suite") @@ -48,7 +49,7 @@ func (s *IntegrationTestSuite) SetupSuite() { newAddr := sdk.AccAddress(info.GetPubKey().Address()) // Send some funds to the new account. - _, err = banktestutil.MsgSendExec( + out, err := banktestutil.MsgSendExec( val.ClientCtx, val.Address, newAddr, @@ -57,9 +58,10 @@ func (s *IntegrationTestSuite) SetupSuite() { fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), ) s.Require().NoError(err) + s.Require().Contains(out.String(), `"code":0`) // grant authorization - _, err = authztestutil.ExecGrantAuthorization(val, []string{ + out, err = authztestutil.ExecGrantAuthorization(val, []string{ newAddr.String(), "send", fmt.Sprintf("--%s=100steak", cli.FlagSpendLimit), @@ -70,6 +72,7 @@ func (s *IntegrationTestSuite) SetupSuite() { fmt.Sprintf("--%s=%d", cli.FlagExpiration, time.Now().Add(time.Minute*time.Duration(120)).Unix()), }) s.Require().NoError(err) + s.Require().Contains(out.String(), `"code":0`) s.grantee = newAddr _, err = s.network.WaitForHeight(1) @@ -185,10 +188,9 @@ func (s *IntegrationTestSuite) TestQueryAuthorizationsGRPC() { fmt.Sprintf("%s/cosmos/authz/v1beta1/granters/%s/grantees/%s/grants", baseURL, val.Address.String(), s.grantee.String()), false, "", - func() { - }, + func() {}, func(authorizations *types.QueryAuthorizationsResponse) { - s.Require().Equal(len(authorizations.Authorizations), 1) + s.Require().Len(authorizations.Authorizations), 1) }, }, { diff --git a/x/authz/client/testutil/tx.go b/x/authz/client/testutil/tx.go index 08c3d706e59e..3b50074219b5 100644 --- a/x/authz/client/testutil/tx.go +++ b/x/authz/client/testutil/tx.go @@ -5,25 +5,22 @@ import ( "time" "github.com/gogo/protobuf/proto" - "github.com/stretchr/testify/suite" + "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/crypto/hd" "github.com/cosmos/cosmos-sdk/crypto/keyring" - - "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/testutil" clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli" "github.com/cosmos/cosmos-sdk/testutil/network" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/authz/client/cli" + banktestutil "github.com/cosmos/cosmos-sdk/x/bank/client/testutil" + bank "github.com/cosmos/cosmos-sdk/x/bank/types" govcli "github.com/cosmos/cosmos-sdk/x/gov/client/cli" govtestutil "github.com/cosmos/cosmos-sdk/x/gov/client/testutil" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" stakingcli "github.com/cosmos/cosmos-sdk/x/staking/client/cli" - - banktestutil "github.com/cosmos/cosmos-sdk/x/bank/client/testutil" - bank "github.com/cosmos/cosmos-sdk/x/bank/types" ) type IntegrationTestSuite struct { @@ -81,7 +78,7 @@ func (s *IntegrationTestSuite) TearDownSuite() { } var typeMsgSend = bank.SendAuthorization{}.MethodName() -var typeMsgVote = "/cosmos.gov.v1beta1.Msg/Vote" +var typeMsgVote = sdk.MsgTypeURL(&govtypes.MsgVote{}) func (s *IntegrationTestSuite) TestCLITxGrantAuthorization() { val := s.network.Validators[0] @@ -93,7 +90,6 @@ func (s *IntegrationTestSuite) TestCLITxGrantAuthorization() { testCases := []struct { name string args []string - respType proto.Message expectedCode uint32 expectErr bool }{ @@ -107,7 +103,6 @@ func (s *IntegrationTestSuite) TestCLITxGrantAuthorization() { fmt.Sprintf("--%s=true", flags.FlagGenerateOnly), fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours), }, - nil, 0, true, }, @@ -121,7 +116,7 @@ func (s *IntegrationTestSuite) TestCLITxGrantAuthorization() { fmt.Sprintf("--%s=true", flags.FlagGenerateOnly), fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours), }, - nil, 0, + 0, true, }, { @@ -134,7 +129,7 @@ func (s *IntegrationTestSuite) TestCLITxGrantAuthorization() { fmt.Sprintf("--%s=true", flags.FlagGenerateOnly), fmt.Sprintf("--%s=%d", cli.FlagExpiration, pastHour), }, - nil, 0, + 0, true, }, { @@ -149,8 +144,8 @@ func (s *IntegrationTestSuite) TestCLITxGrantAuthorization() { fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours), }, - nil, 0, - true, + 0x1d, + false, }, { "failed with error both validators not allowed", @@ -166,7 +161,7 @@ func (s *IntegrationTestSuite) TestCLITxGrantAuthorization() { fmt.Sprintf("--%s=%s", cli.FlagDenyValidators, val.ValAddress.String()), fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), }, - nil, 0, + 0, true, }, { @@ -182,7 +177,7 @@ func (s *IntegrationTestSuite) TestCLITxGrantAuthorization() { fmt.Sprintf("--%s=%s", cli.FlagAllowedValidators, val.ValAddress.String()), fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), }, - &sdk.TxResponse{}, 0, + 0, false, }, { @@ -198,7 +193,7 @@ func (s *IntegrationTestSuite) TestCLITxGrantAuthorization() { fmt.Sprintf("--%s=%s", cli.FlagDenyValidators, val.ValAddress.String()), fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), }, - &sdk.TxResponse{}, 0, + 0, false, }, { @@ -214,7 +209,7 @@ func (s *IntegrationTestSuite) TestCLITxGrantAuthorization() { fmt.Sprintf("--%s=%s", cli.FlagAllowedValidators, val.ValAddress.String()), fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), }, - &sdk.TxResponse{}, 0, + 0, false, }, { @@ -230,7 +225,7 @@ func (s *IntegrationTestSuite) TestCLITxGrantAuthorization() { fmt.Sprintf("--%s=%s", cli.FlagAllowedValidators, val.ValAddress.String()), fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), }, - &sdk.TxResponse{}, 0, + 0, false, }, { @@ -245,7 +240,7 @@ func (s *IntegrationTestSuite) TestCLITxGrantAuthorization() { fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), }, - &sdk.TxResponse{}, 0, + 0, false, }, { @@ -260,7 +255,7 @@ func (s *IntegrationTestSuite) TestCLITxGrantAuthorization() { fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), }, - &sdk.TxResponse{}, 0, + 0, false, }, } @@ -276,9 +271,9 @@ func (s *IntegrationTestSuite) TestCLITxGrantAuthorization() { if tc.expectErr { s.Require().Error(err) } else { + var txResp sdk.TxResponse s.Require().NoError(err) - s.Require().NoError(clientCtx.JSONMarshaler.UnmarshalJSON(out.Bytes(), tc.respType), out.String()) - txResp := tc.respType.(*sdk.TxResponse) + s.Require().NoError(clientCtx.JSONMarshaler.UnmarshalJSON(out.Bytes(), &txResp), out.String()) s.Require().Equal(tc.expectedCode, txResp.Code, out.String()) } }) @@ -427,7 +422,7 @@ func (s *IntegrationTestSuite) TestExecAuthorizationWithExpiration() { ) s.Require().NoError(err) // msg vote - voteTx := fmt.Sprintf(`{"body":{"messages":[{"@type":"/cosmos.gov.v1beta1.Msg/Vote","proposal_id":"1","voter":"%s","option":"VOTE_OPTION_YES"}],"memo":"","timeout_height":"0","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[],"fee":{"amount":[],"gas_limit":"200000","payer":"","granter":""}},"signatures":[]}`, val.Address.String()) + voteTx := fmt.Sprintf(`{"body":{"messages":[{"@type":"/cosmos.gov.v1beta1.MsgVote","proposal_id":"1","voter":"%s","option":"VOTE_OPTION_YES"}],"memo":"","timeout_height":"0","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[],"fee":{"amount":[],"gas_limit":"200000","payer":"","granter":""}},"signatures":[]}`, val.Address.String()) execMsg := testutil.WriteToNewTempFile(s.T(), voteTx) // waiting for authorization to expires @@ -468,7 +463,7 @@ func (s *IntegrationTestSuite) TestNewExecGenericAuthorized() { s.Require().NoError(err) // msg vote - voteTx := fmt.Sprintf(`{"body":{"messages":[{"@type":"/cosmos.gov.v1beta1.Msg/Vote","proposal_id":"1","voter":"%s","option":"VOTE_OPTION_YES"}],"memo":"","timeout_height":"0","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[],"fee":{"amount":[],"gas_limit":"200000","payer":"","granter":""}},"signatures":[]}`, val.Address.String()) + voteTx := fmt.Sprintf(`{"body":{"messages":[{"@type":"/cosmos.gov.v1beta1.MsgVote","proposal_id":"1","voter":"%s","option":"VOTE_OPTION_YES"}],"memo":"","timeout_height":"0","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[],"fee":{"amount":[],"gas_limit":"200000","payer":"","granter":""}},"signatures":[]}`, val.Address.String()) execMsg := testutil.WriteToNewTempFile(s.T(), voteTx) testCases := []struct { @@ -646,7 +641,7 @@ func (s *IntegrationTestSuite) TestExecDelegateAuthorization() { sdk.NewCoin("stake", sdk.NewInt(50)), ) - delegateTx := fmt.Sprintf(`{"body":{"messages":[{"@type":"/cosmos.staking.v1beta1.Msg/Delegate","delegator_address":"%s","validator_address":"%s","amount":{"denom":"%s","amount":"%s"}}],"memo":"","timeout_height":"0","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[],"fee":{"amount":[],"gas_limit":"200000","payer":"","granter":""}},"signatures":[]}`, val.Address.String(), val.ValAddress.String(), + delegateTx := fmt.Sprintf(`{"body":{"messages":[{"@type":"/cosmos.staking.v1beta1.MsgDelegate","delegator_address":"%s","validator_address":"%s","amount":{"denom":"%s","amount":"%s"}}],"memo":"","timeout_height":"0","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[],"fee":{"amount":[],"gas_limit":"200000","payer":"","granter":""}},"signatures":[]}`, val.Address.String(), val.ValAddress.String(), tokens.GetDenomByIndex(0), tokens[0].Amount) execMsg := testutil.WriteToNewTempFile(s.T(), delegateTx) @@ -736,7 +731,7 @@ func (s *IntegrationTestSuite) TestExecDelegateAuthorization() { sdk.NewCoin("stake", sdk.NewInt(50)), ) - delegateTx = fmt.Sprintf(`{"body":{"messages":[{"@type":"/cosmos.staking.v1beta1.Msg/Delegate","delegator_address":"%s","validator_address":"%s","amount":{"denom":"%s","amount":"%s"}}],"memo":"","timeout_height":"0","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[],"fee":{"amount":[],"gas_limit":"200000","payer":"","granter":""}},"signatures":[]}`, val.Address.String(), val.ValAddress.String(), + delegateTx = fmt.Sprintf(`{"body":{"messages":[{"@type":"/cosmos.staking.v1beta1.MsgDelegate","delegator_address":"%s","validator_address":"%s","amount":{"denom":"%s","amount":"%s"}}],"memo":"","timeout_height":"0","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[],"fee":{"amount":[],"gas_limit":"200000","payer":"","granter":""}},"signatures":[]}`, val.Address.String(), val.ValAddress.String(), tokens.GetDenomByIndex(0), tokens[0].Amount) execMsg = testutil.WriteToNewTempFile(s.T(), delegateTx) @@ -822,7 +817,6 @@ func (s *IntegrationTestSuite) TestExecDelegateAuthorization() { out, err := clitestutil.ExecTestCLICmd(val.ClientCtx, cmd, args) s.Require().NoError(err) s.Contains(out.String(), fmt.Sprintf("cannot delegate/undelegate to %s validator", val.ValAddress.String())) - } func (s *IntegrationTestSuite) TestExecUndelegateAuthorization() { @@ -865,7 +859,7 @@ func (s *IntegrationTestSuite) TestExecUndelegateAuthorization() { sdk.NewCoin("stake", sdk.NewInt(50)), ) - undelegateTx := fmt.Sprintf(`{"body":{"messages":[{"@type":"/cosmos.staking.v1beta1.Msg/Undelegate","delegator_address":"%s","validator_address":"%s","amount":{"denom":"%s","amount":"%s"}}],"memo":"","timeout_height":"0","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[],"fee":{"amount":[],"gas_limit":"200000","payer":"","granter":""}},"signatures":[]}`, val.Address.String(), val.ValAddress.String(), + undelegateTx := fmt.Sprintf(`{"body":{"messages":[{"@type":"/cosmos.staking.v1beta1.MsgUndelegate","delegator_address":"%s","validator_address":"%s","amount":{"denom":"%s","amount":"%s"}}],"memo":"","timeout_height":"0","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[],"fee":{"amount":[],"gas_limit":"200000","payer":"","granter":""}},"signatures":[]}`, val.Address.String(), val.ValAddress.String(), tokens.GetDenomByIndex(0), tokens[0].Amount) execMsg := testutil.WriteToNewTempFile(s.T(), undelegateTx) @@ -955,7 +949,7 @@ func (s *IntegrationTestSuite) TestExecUndelegateAuthorization() { sdk.NewCoin("stake", sdk.NewInt(50)), ) - undelegateTx = fmt.Sprintf(`{"body":{"messages":[{"@type":"/cosmos.staking.v1beta1.Msg/Undelegate","delegator_address":"%s","validator_address":"%s","amount":{"denom":"%s","amount":"%s"}}],"memo":"","timeout_height":"0","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[],"fee":{"amount":[],"gas_limit":"200000","payer":"","granter":""}},"signatures":[]}`, val.Address.String(), val.ValAddress.String(), + undelegateTx = fmt.Sprintf(`{"body":{"messages":[{"@type":"/cosmos.staking.v1beta1.MsgUndelegate","delegator_address":"%s","validator_address":"%s","amount":{"denom":"%s","amount":"%s"}}],"memo":"","timeout_height":"0","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[],"fee":{"amount":[],"gas_limit":"200000","payer":"","granter":""}},"signatures":[]}`, val.Address.String(), val.ValAddress.String(), tokens.GetDenomByIndex(0), tokens[0].Amount) execMsg = testutil.WriteToNewTempFile(s.T(), undelegateTx) diff --git a/x/authz/exported/authorizations.go b/x/authz/exported/authorizations.go index 32fea0b0b3a8..c065c9f65072 100644 --- a/x/authz/exported/authorizations.go +++ b/x/authz/exported/authorizations.go @@ -15,7 +15,7 @@ type Authorization interface { // Accept determines whether this grant permits the provided sdk.ServiceMsg to be performed, and if // so provides an upgraded authorization instance. - Accept(ctx sdk.Context, msg sdk.ServiceMsg) (updated Authorization, delete bool, err error) + Accept(ctx sdk.Context, msg sdk.Msg) (updated Authorization, delete bool, err error) // ValidateBasic does a simple validation check that // doesn't require access to any other information. diff --git a/x/authz/keeper/keeper.go b/x/authz/keeper/keeper.go index 42acd0d77405..88416b88710f 100644 --- a/x/authz/keeper/keeper.go +++ b/x/authz/keeper/keeper.go @@ -73,26 +73,29 @@ func (k Keeper) update(ctx sdk.Context, grantee sdk.AccAddress, granter sdk.AccA // DispatchActions attempts to execute the provided messages via authorization // grants from the message signer to the grantee. -func (k Keeper) DispatchActions(ctx sdk.Context, grantee sdk.AccAddress, serviceMsgs []sdk.ServiceMsg) (*sdk.Result, error) { +func (k Keeper) DispatchActions(ctx sdk.Context, grantee sdk.AccAddress, msgs []sdk.Msg) (*sdk.Result, error) { var msgResult *sdk.Result var err error - for _, serviceMsg := range serviceMsgs { - signers := serviceMsg.GetSigners() + for _, msg := range msgs { + signers := msg.GetSigners() if len(signers) != 1 { return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "authorization can be given to msg with only one signer") } granter := signers[0] if !granter.Equals(grantee) { - authorization, _ := k.GetOrRevokeAuthorization(ctx, grantee, granter, serviceMsg.MethodName) + authorization, _ := k.GetOrRevokeAuthorization(ctx, grantee, granter, sdk.MsgTypeURL(msg)) if authorization == nil { return nil, sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, "authorization not found") } - updated, del, err := authorization.Accept(ctx, serviceMsg) + updated, del, err := authorization.Accept(ctx, msg) if err != nil { return nil, err } if del { - k.Revoke(ctx, grantee, granter, serviceMsg.Type()) + err = k.Revoke(ctx, grantee, granter, sdk.MsgTypeURL(msg)) + if err != nil { + return nil, err + } } else if updated != nil { err = k.update(ctx, grantee, granter, updated) if err != nil { @@ -100,15 +103,15 @@ func (k Keeper) DispatchActions(ctx sdk.Context, grantee sdk.AccAddress, service } } } - handler := k.router.Handler(serviceMsg.Route()) + handler := k.router.Handler(msg) if handler == nil { - return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized message route: %s", serviceMsg.Route()) + return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized message route: %s", sdk.MsgTypeURL(msg)) } - msgResult, err = handler(ctx, serviceMsg.Request) + msgResult, err = handler(ctx, msg) if err != nil { - return nil, sdkerrors.Wrapf(err, "failed to execute message; message %s", serviceMsg.MethodName) + return nil, sdkerrors.Wrapf(err, "failed to execute message; message %v", msg) } } diff --git a/x/authz/keeper/keeper_test.go b/x/authz/keeper/keeper_test.go index 161fed6e98bd..91ea9b5fcbd1 100644 --- a/x/authz/keeper/keeper_test.go +++ b/x/authz/keeper/keeper_test.go @@ -4,15 +4,11 @@ import ( "testing" "time" - proto "github.com/gogo/protobuf/proto" - - "github.com/cosmos/cosmos-sdk/baseapp" - + "github.com/stretchr/testify/suite" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" tmtime "github.com/tendermint/tendermint/types/time" - "github.com/stretchr/testify/suite" - + "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/simapp" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/authz/types" @@ -42,7 +38,6 @@ func (s *TestSuite) SetupTest() { s.ctx = ctx s.queryClient = queryClient s.addrs = simapp.AddTestAddrsIncremental(app, ctx, 3, sdk.NewInt(30000000)) - } func (s *TestSuite) TestKeeper() { @@ -76,7 +71,7 @@ func (s *TestSuite) TestKeeper() { s.Require().Equal(authorization.MethodName(), banktypes.SendAuthorization{}.MethodName()) s.T().Log("verify fetching authorization with wrong msg type fails") - authorization, _ = app.AuthzKeeper.GetOrRevokeAuthorization(ctx, granteeAddr, granterAddr, proto.MessageName(&banktypes.MsgMultiSend{})) + authorization, _ = app.AuthzKeeper.GetOrRevokeAuthorization(ctx, granteeAddr, granterAddr, sdk.MsgTypeURL(&banktypes.MsgMultiSend{})) s.Require().Nil(authorization) s.T().Log("verify fetching authorization with wrong grantee fails") @@ -139,21 +134,18 @@ func (s *TestSuite) TestKeeperFees() { smallCoin := sdk.NewCoins(sdk.NewInt64Coin("steak", 20)) someCoin := sdk.NewCoins(sdk.NewInt64Coin("steak", 123)) - msgs := types.NewMsgExecAuthorized(granteeAddr, []sdk.ServiceMsg{ - { - MethodName: banktypes.SendAuthorization{}.MethodName(), - Request: &banktypes.MsgSend{ - Amount: sdk.NewCoins(sdk.NewInt64Coin("steak", 2)), - FromAddress: granterAddr.String(), - ToAddress: recipientAddr.String(), - }, + msgs := types.NewMsgExecAuthorized(granteeAddr, []sdk.Msg{ + &banktypes.MsgSend{ + Amount: sdk.NewCoins(sdk.NewInt64Coin("steak", 2)), + FromAddress: granterAddr.String(), + ToAddress: recipientAddr.String(), }, }) s.Require().NoError(msgs.UnpackInterfaces(app.AppCodec())) s.T().Log("verify dispatch fails with invalid authorization") - executeMsgs, err := msgs.GetServiceMsgs() + executeMsgs, err := msgs.GetMessages() s.Require().NoError(err) result, err := app.AuthzKeeper.DispatchActions(s.ctx, granteeAddr, executeMsgs) @@ -169,7 +161,7 @@ func (s *TestSuite) TestKeeperFees() { s.Require().Equal(authorization.MethodName(), banktypes.SendAuthorization{}.MethodName()) - executeMsgs, err = msgs.GetServiceMsgs() + executeMsgs, err = msgs.GetMessages() s.Require().NoError(err) result, err = app.AuthzKeeper.DispatchActions(s.ctx, granteeAddr, executeMsgs) @@ -182,19 +174,16 @@ func (s *TestSuite) TestKeeperFees() { s.T().Log("verify dispatch fails with overlimit") // grant authorization - msgs = types.NewMsgExecAuthorized(granteeAddr, []sdk.ServiceMsg{ - { - MethodName: banktypes.SendAuthorization{}.MethodName(), - Request: &banktypes.MsgSend{ - Amount: someCoin, - FromAddress: granterAddr.String(), - ToAddress: recipientAddr.String(), - }, + msgs = types.NewMsgExecAuthorized(granteeAddr, []sdk.Msg{ + &banktypes.MsgSend{ + Amount: someCoin, + FromAddress: granterAddr.String(), + ToAddress: recipientAddr.String(), }, }) s.Require().NoError(msgs.UnpackInterfaces(app.AppCodec())) - executeMsgs, err = msgs.GetServiceMsgs() + executeMsgs, err = msgs.GetMessages() s.Require().NoError(err) result, err = app.AuthzKeeper.DispatchActions(s.ctx, granteeAddr, executeMsgs) diff --git a/x/authz/keeper/msg_server.go b/x/authz/keeper/msg_server.go index 53beb129dfaa..85c5ff262b58 100644 --- a/x/authz/keeper/msg_server.go +++ b/x/authz/keeper/msg_server.go @@ -24,7 +24,7 @@ func (k Keeper) GrantAuthorization(goCtx context.Context, msg *types.MsgGrantAut authorization := msg.GetGrantAuthorization() // If the granted service Msg doesn't exist, we throw an error. - if k.router.Handler(authorization.MethodName()) == nil { + if k.router.HandlerbyTypeURL(authorization.MethodName()) == nil { return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "%s doesn't exist.", authorization.MethodName()) } @@ -63,7 +63,7 @@ func (k Keeper) ExecAuthorized(goCtx context.Context, msg *types.MsgExecAuthoriz if err != nil { return nil, err } - msgs, err := msg.GetServiceMsgs() + msgs, err := msg.GetMessages() if err != nil { return nil, err } diff --git a/x/authz/simulation/operations.go b/x/authz/simulation/operations.go index b01296d8bc11..6b3c0f6ab10b 100644 --- a/x/authz/simulation/operations.go +++ b/x/authz/simulation/operations.go @@ -20,10 +20,12 @@ import ( ) // authz message types -const ( - TypeMsgGrantAuthorization = "/cosmos.authz.v1beta1.Msg/GrantAuthorization" - TypeMsgRevokeAuthorization = "/cosmos.authz.v1beta1.Msg/RevokeAuthorization" - TypeMsgExecDelegated = "/cosmos.authz.v1beta1.Msg/ExecAuthorized" +var ( + // TODO Remove `Request` suffix + // https://github.com/cosmos/cosmos-sdk/issues/9114 + TypeMsgGrantAuthorization = sdk.MsgTypeURL(&types.MsgGrantAuthorizationRequest{}) + TypeMsgRevokeAuthorization = sdk.MsgTypeURL(&types.MsgRevokeAuthorizationRequest{}) + TypeMsgExecDelegated = sdk.MsgTypeURL(&types.MsgExecAuthorizedRequest{}) ) // Simulation operation weights constants @@ -130,7 +132,7 @@ func SimulateMsgGrantAuthorization(ak types.AccountKeeper, bk types.BankKeeper, _, _, err = app.Deliver(txGen.TxEncoder(), tx) if err != nil { - return simtypes.NoOpMsg(types.ModuleName, svcMsgClientConn.GetMsgs()[0].Type(), "unable to deliver tx"), nil, err + return simtypes.NoOpMsg(types.ModuleName, sdk.MsgTypeURL(svcMsgClientConn.GetMsgs()[0]), "unable to deliver tx"), nil, err } return simtypes.NewOperationMsg(svcMsgClientConn.GetMsgs()[0], true, "", protoCdc), nil, err } @@ -242,16 +244,13 @@ func SimulateMsgExecuteAuthorized(ak types.AccountKeeper, bk types.BankKeeper, k } sendCoins := sdk.NewCoins(sdk.NewCoin("foo", sdk.NewInt(10))) - execMsg := sdk.ServiceMsg{ - MethodName: banktype.SendAuthorization{}.MethodName(), - Request: banktype.NewMsgSend( - granterAddr, - granteeAddr, - sendCoins, - ), - } + execMsg := banktype.NewMsgSend( + granterAddr, + granteeAddr, + sendCoins, + ) - msg := types.NewMsgExecAuthorized(grantee.Address, []sdk.ServiceMsg{execMsg}) + msg := types.NewMsgExecAuthorized(grantee.Address, []sdk.Msg{execMsg}) sendGrant := targetGrant.Authorization.GetCachedValue().(*banktype.SendAuthorization) _, _, err = sendGrant.Accept(ctx, execMsg) if err != nil { diff --git a/x/authz/types/codec.go b/x/authz/types/codec.go index c6119f2a0bbb..dd68cf0bc126 100644 --- a/x/authz/types/codec.go +++ b/x/authz/types/codec.go @@ -11,7 +11,7 @@ import ( // RegisterInterfaces registers the interfaces types with the interface registry func RegisterInterfaces(registry types.InterfaceRegistry) { - registry.RegisterImplementations((*sdk.MsgRequest)(nil), + registry.RegisterImplementations((*sdk.Msg)(nil), &MsgGrantAuthorizationRequest{}, &MsgRevokeAuthorizationRequest{}, &MsgExecAuthorizedRequest{}, diff --git a/x/authz/types/generic_authorization.go b/x/authz/types/generic_authorization.go index 101f3acf1664..67af64c99dcf 100644 --- a/x/authz/types/generic_authorization.go +++ b/x/authz/types/generic_authorization.go @@ -2,8 +2,6 @@ package types import ( sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - "github.com/cosmos/cosmos-sdk/types/msgservice" "github.com/cosmos/cosmos-sdk/x/authz/exported" ) @@ -24,14 +22,11 @@ func (authorization GenericAuthorization) MethodName() string { } // Accept implements Authorization.Accept. -func (authorization GenericAuthorization) Accept(ctx sdk.Context, msg sdk.ServiceMsg) (updated exported.Authorization, delete bool, err error) { +func (authorization GenericAuthorization) Accept(ctx sdk.Context, msg sdk.Msg) (updated exported.Authorization, delete bool, err error) { return &authorization, false, nil } // ValidateBasic implements Authorization.ValidateBasic. func (authorization GenericAuthorization) ValidateBasic() error { - if !msgservice.IsServiceMsg(authorization.MessageName) { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidType, " %s is not a valid service msg", authorization.MessageName) - } return nil } diff --git a/x/authz/types/generic_authorization_test.go b/x/authz/types/generic_authorization_test.go index 2dda401c693f..a5ffe0803a81 100644 --- a/x/authz/types/generic_authorization_test.go +++ b/x/authz/types/generic_authorization_test.go @@ -10,12 +10,8 @@ import ( ) func TestGenericAuthorization(t *testing.T) { - t.Log("verify ValidateBasic returns error for non-service msg") - authorization := types.NewGenericAuthorization(banktypes.TypeMsgSend) - require.Error(t, authorization.ValidateBasic()) - t.Log("verify ValidateBasic returns nil for service msg") - authorization = types.NewGenericAuthorization(banktypes.SendAuthorization{}.MethodName()) + authorization := types.NewGenericAuthorization(banktypes.SendAuthorization{}.MethodName()) require.NoError(t, authorization.ValidateBasic()) require.Equal(t, banktypes.SendAuthorization{}.MethodName(), authorization.MessageName) } diff --git a/x/authz/types/msgs.go b/x/authz/types/msgs.go index 0b72d1a7e869..bdb38ccc915f 100644 --- a/x/authz/types/msgs.go +++ b/x/authz/types/msgs.go @@ -12,9 +12,9 @@ import ( ) var ( - _ sdk.MsgRequest = &MsgGrantAuthorizationRequest{} - _ sdk.MsgRequest = &MsgRevokeAuthorizationRequest{} - _ sdk.MsgRequest = &MsgExecAuthorizedRequest{} + _ sdk.Msg = &MsgGrantAuthorizationRequest{} + _ sdk.Msg = &MsgRevokeAuthorizationRequest{} + _ sdk.Msg = &MsgExecAuthorizedRequest{} _ types.UnpackInterfacesMessage = &MsgGrantAuthorizationRequest{} _ types.UnpackInterfacesMessage = &MsgExecAuthorizedRequest{} @@ -96,7 +96,7 @@ func (msg *MsgGrantAuthorizationRequest) SetAuthorization(authorization exported // UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces func (msg MsgExecAuthorizedRequest) UnpackInterfaces(unpacker types.AnyUnpacker) error { for _, x := range msg.Msgs { - var msgExecAuthorized sdk.MsgRequest + var msgExecAuthorized sdk.Msg err := unpacker.UnpackAny(x, &msgExecAuthorized) if err != nil { return err @@ -155,20 +155,15 @@ func (msg MsgRevokeAuthorizationRequest) ValidateBasic() error { // NewMsgExecAuthorized creates a new MsgExecAuthorized //nolint:interfacer -func NewMsgExecAuthorized(grantee sdk.AccAddress, msgs []sdk.ServiceMsg) MsgExecAuthorizedRequest { +func NewMsgExecAuthorized(grantee sdk.AccAddress, msgs []sdk.Msg) MsgExecAuthorizedRequest { msgsAny := make([]*types.Any, len(msgs)) for i, msg := range msgs { - bz, err := proto.Marshal(msg.Request) + any, err := types.NewAnyWithValue(msg) if err != nil { panic(err) } - anyMsg := &types.Any{ - TypeUrl: msg.MethodName, - Value: bz, - } - - msgsAny[i] = anyMsg + msgsAny[i] = any } return MsgExecAuthorizedRequest{ @@ -177,20 +172,15 @@ func NewMsgExecAuthorized(grantee sdk.AccAddress, msgs []sdk.ServiceMsg) MsgExec } } -// GetServiceMsgs returns the cache values from the MsgExecAuthorized.Msgs if present. -func (msg MsgExecAuthorizedRequest) GetServiceMsgs() ([]sdk.ServiceMsg, error) { - msgs := make([]sdk.ServiceMsg, len(msg.Msgs)) +// GetMessages returns the cache values from the MsgExecAuthorized.Msgs if present. +func (msg MsgExecAuthorizedRequest) GetMessages() ([]sdk.Msg, error) { + msgs := make([]sdk.Msg, len(msg.Msgs)) for i, msgAny := range msg.Msgs { - msgReq, ok := msgAny.GetCachedValue().(sdk.MsgRequest) + msg, ok := msgAny.GetCachedValue().(sdk.Msg) if !ok { return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "messages contains %T which is not a sdk.MsgRequest", msgAny) } - srvMsg := sdk.ServiceMsg{ - MethodName: msgAny.TypeUrl, - Request: msgReq, - } - - msgs[i] = srvMsg + msgs[i] = msg } return msgs, nil diff --git a/x/authz/types/msgs_test.go b/x/authz/types/msgs_test.go index c27c750b0d93..9062cc9b0967 100644 --- a/x/authz/types/msgs_test.go +++ b/x/authz/types/msgs_test.go @@ -23,19 +23,16 @@ func TestMsgExecAuthorized(t *testing.T) { tests := []struct { title string grantee sdk.AccAddress - msgs []sdk.ServiceMsg + msgs []sdk.Msg expectPass bool }{ - {"nil grantee address", nil, []sdk.ServiceMsg{}, false}, - {"zero-messages test: should fail", grantee, []sdk.ServiceMsg{}, false}, - {"valid test: msg type", grantee, []sdk.ServiceMsg{ - { - MethodName: banktypes.SendAuthorization{}.MethodName(), - Request: &banktypes.MsgSend{ - Amount: sdk.NewCoins(sdk.NewInt64Coin("steak", 2)), - FromAddress: granter.String(), - ToAddress: grantee.String(), - }, + {"nil grantee address", nil, []sdk.Msg{}, false}, + {"zero-messages test: should fail", grantee, []sdk.Msg{}, false}, + {"valid test: msg type", grantee, []sdk.Msg{ + &banktypes.MsgSend{ + Amount: sdk.NewCoins(sdk.NewInt64Coin("steak", 2)), + FromAddress: granter.String(), + ToAddress: grantee.String(), }, }, true}, } diff --git a/x/bank/client/testutil/cli_helpers.go b/x/bank/client/testutil/cli_helpers.go index 57a5a5798edc..a1a33c4f67bc 100644 --- a/x/bank/client/testutil/cli_helpers.go +++ b/x/bank/client/testutil/cli_helpers.go @@ -1,22 +1,14 @@ package testutil import ( - "context" "fmt" "github.com/tendermint/tendermint/libs/cli" "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/tx" "github.com/cosmos/cosmos-sdk/testutil" clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli" - "github.com/cosmos/cosmos-sdk/testutil/testdata" - sdk "github.com/cosmos/cosmos-sdk/types" - txtypes "github.com/cosmos/cosmos-sdk/types/tx" - "github.com/cosmos/cosmos-sdk/types/tx/signing" - authclient "github.com/cosmos/cosmos-sdk/x/auth/client" bankcli "github.com/cosmos/cosmos-sdk/x/bank/client/cli" - "github.com/cosmos/cosmos-sdk/x/bank/types" ) func MsgSendExec(clientCtx client.Context, from, to, amount fmt.Stringer, extraArgs ...string) (testutil.BufferWriter, error) { @@ -32,56 +24,3 @@ func QueryBalancesExec(clientCtx client.Context, address fmt.Stringer, extraArgs return clitestutil.ExecTestCLICmd(clientCtx, bankcli.GetBalancesCmd(), args) } - -// LegacyGRPCProtoMsgSend is a legacy method to broadcast a legacy proto MsgSend. -// -// Deprecated. -//nolint:interfacer -func LegacyGRPCProtoMsgSend(clientCtx client.Context, keyName string, from, to sdk.Address, fee, amount []sdk.Coin, extraArgs ...string) (*txtypes.BroadcastTxResponse, error) { - // prepare txBuilder with msg - txBuilder := clientCtx.TxConfig.NewTxBuilder() - feeAmount := fee - gasLimit := testdata.NewTestGasLimit() - - // This sets a legacy Proto MsgSend. - err := txBuilder.SetMsgs(&types.MsgSend{ - FromAddress: from.String(), - ToAddress: to.String(), - Amount: amount, - }) - if err != nil { - return nil, err - } - - txBuilder.SetFeeAmount(feeAmount) - txBuilder.SetGasLimit(gasLimit) - - // setup txFactory - txFactory := tx.Factory{}. - WithChainID(clientCtx.ChainID). - WithKeybase(clientCtx.Keyring). - WithTxConfig(clientCtx.TxConfig). - WithSignMode(signing.SignMode_SIGN_MODE_DIRECT) - - // Sign Tx. - err = authclient.SignTx(txFactory, clientCtx, keyName, txBuilder, false, true) - if err != nil { - return nil, err - } - - txBytes, err := clientCtx.TxConfig.TxEncoder()(txBuilder.GetTx()) - if err != nil { - return nil, err - } - - // Broadcast the tx via gRPC. - queryClient := txtypes.NewServiceClient(clientCtx) - - return queryClient.BroadcastTx( - context.Background(), - &txtypes.BroadcastTxRequest{ - Mode: txtypes.BroadcastMode_BROADCAST_MODE_SYNC, - TxBytes: txBytes, - }, - ) -} diff --git a/x/bank/client/testutil/suite.go b/x/bank/client/testutil/suite.go index d56835f9b68f..342c780253e0 100644 --- a/x/bank/client/testutil/suite.go +++ b/x/bank/client/testutil/suite.go @@ -383,10 +383,7 @@ func (s *IntegrationTestSuite) TestNewSendTxCmdGenOnly() { s.Require().NoError(err) tx, err := s.cfg.TxConfig.TxJSONDecoder()(bz.Bytes()) s.Require().NoError(err) - s.Require().Equal([]sdk.Msg{sdk.ServiceMsg{ - MethodName: "/cosmos.bank.v1beta1.Msg/Send", - Request: types.NewMsgSend(from, to, amount), - }}, tx.GetMsgs()) + s.Require().Equal([]sdk.Msg{types.NewMsgSend(from, to, amount)}, tx.GetMsgs()) } func (s *IntegrationTestSuite) TestNewSendTxCmd() { @@ -473,62 +470,6 @@ func (s *IntegrationTestSuite) TestNewSendTxCmd() { } } -// TestBankMsgService does a basic test of whether or not service Msg's as defined -// in ADR 031 work in the most basic end-to-end case. -func (s *IntegrationTestSuite) TestBankMsgService() { - val := s.network.Validators[0] - - testCases := []struct { - name string - from, to sdk.AccAddress - amount sdk.Coins - args []string - expectErr bool - expectedCode uint32 - respType proto.Message - rawLogContains string - }{ - { - "valid transaction", - val.Address, - val.Address, - sdk.NewCoins( - sdk.NewCoin(fmt.Sprintf("%stoken", val.Moniker), sdk.NewInt(10)), - sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10)), - ), - []string{ - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), - }, - false, - 0, - &sdk.TxResponse{}, - "/cosmos.bank.v1beta1.Msg/Send", // indicates we are using ServiceMsg and not a regular Msg - }, - } - - for _, tc := range testCases { - tc := tc - - s.Run(tc.name, func() { - clientCtx := val.ClientCtx - - bz, err := MsgSendExec(clientCtx, tc.from, tc.to, tc.amount, tc.args...) - if tc.expectErr { - s.Require().Error(err) - } else { - s.Require().NoError(err) - - s.Require().NoError(clientCtx.JSONMarshaler.UnmarshalJSON(bz.Bytes(), tc.respType), bz.String()) - txResp := tc.respType.(*sdk.TxResponse) - s.Require().Equal(tc.expectedCode, txResp.Code) - s.Require().Contains(txResp.RawLog, tc.rawLogContains) - } - }) - } -} - func NewCoin(denom string, amount sdk.Int) *sdk.Coin { coin := sdk.NewCoin(denom, amount) return &coin diff --git a/x/bank/types/send_authorization.go b/x/bank/types/send_authorization.go index 82d1bf1e630b..758526f64fa1 100644 --- a/x/bank/types/send_authorization.go +++ b/x/bank/types/send_authorization.go @@ -1,8 +1,6 @@ package types import ( - "reflect" - sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" authz "github.com/cosmos/cosmos-sdk/x/authz/exported" @@ -21,26 +19,25 @@ func NewSendAuthorization(spendLimit sdk.Coins) *SendAuthorization { // MethodName implements Authorization.MethodName. func (authorization SendAuthorization) MethodName() string { - return "/cosmos.bank.v1beta1.Msg/Send" + return sdk.MsgTypeURL(&MsgSend{}) } // Accept implements Authorization.Accept. -func (authorization SendAuthorization) Accept(ctx sdk.Context, msg sdk.ServiceMsg) (updated authz.Authorization, delete bool, err error) { - if reflect.TypeOf(msg.Request) == reflect.TypeOf(&MsgSend{}) { - msg, ok := msg.Request.(*MsgSend) - if ok { - limitLeft, isNegative := authorization.SpendLimit.SafeSub(msg.Amount) - if isNegative { - return nil, false, sdkerrors.Wrapf(sdkerrors.ErrInsufficientFunds, "requested amount is more than spend limit") - } - if limitLeft.IsZero() { - return nil, true, nil - } - - return &SendAuthorization{SpendLimit: limitLeft}, false, nil - } +func (authorization SendAuthorization) Accept(_ sdk.Context, msg sdk.Msg) (updated authz.Authorization, delete bool, err error) { + msgSend, ok := msg.(*MsgSend) + if !ok { + return nil, false, sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "type mismatch") + } + + limitLeft, isNegative := authorization.SpendLimit.SafeSub(msgSend.Amount) + if isNegative { + return nil, false, sdkerrors.Wrapf(sdkerrors.ErrInsufficientFunds, "requested amount is more than spend limit") } - return nil, false, sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "type mismatch") + if limitLeft.IsZero() { + return nil, true, nil + } + + return &SendAuthorization{SpendLimit: limitLeft}, false, nil } // ValidateBasic implements Authorization.ValidateBasic. diff --git a/x/bank/types/send_authorization_test.go b/x/bank/types/send_authorization_test.go index 45bb718cd847..8ff979763612 100644 --- a/x/bank/types/send_authorization_test.go +++ b/x/bank/types/send_authorization_test.go @@ -24,31 +24,24 @@ func TestSendAuthorization(t *testing.T) { authorization := types.NewSendAuthorization(coins1000) t.Log("verify authorization returns valid method name") - require.Equal(t, authorization.MethodName(), "/cosmos.bank.v1beta1.Msg/Send") + require.Equal(t, authorization.MethodName(), "/cosmos.bank.v1beta1.MsgSend") require.NoError(t, authorization.ValidateBasic()) send := types.NewMsgSend(fromAddr, toAddr, coins1000) - srvMsg := sdk.ServiceMsg{ - MethodName: "/cosmos.bank.v1beta1.Msg/Send", - Request: send, - } + require.NoError(t, authorization.ValidateBasic()) t.Log("verify updated authorization returns nil") - updated, del, err := authorization.Accept(ctx, srvMsg) + updated, del, err := authorization.Accept(ctx, send) require.NoError(t, err) require.True(t, del) require.Nil(t, updated) authorization = types.NewSendAuthorization(coins1000) - require.Equal(t, authorization.MethodName(), "/cosmos.bank.v1beta1.Msg/Send") + require.Equal(t, authorization.MethodName(), "/cosmos.bank.v1beta1.MsgSend") require.NoError(t, authorization.ValidateBasic()) send = types.NewMsgSend(fromAddr, toAddr, coins500) - srvMsg = sdk.ServiceMsg{ - MethodName: "/cosmos.bank.v1beta1.Msg/Send", - Request: send, - } require.NoError(t, authorization.ValidateBasic()) - updated, del, err = authorization.Accept(ctx, srvMsg) + updated, del, err = authorization.Accept(ctx, send) t.Log("verify updated authorization returns remaining spent limit") require.NoError(t, err) @@ -58,7 +51,7 @@ func TestSendAuthorization(t *testing.T) { require.Equal(t, sendAuth.String(), updated.String()) t.Log("expect updated authorization nil after spending remaining amount") - updated, del, err = updated.Accept(ctx, srvMsg) + updated, del, err = updated.Accept(ctx, send) require.NoError(t, err) require.True(t, del) require.Nil(t, updated) diff --git a/x/evidence/types/msgs_test.go b/x/evidence/types/msgs_test.go index 4248b0dfba94..ee1ed509bca5 100644 --- a/x/evidence/types/msgs_test.go +++ b/x/evidence/types/msgs_test.go @@ -8,6 +8,7 @@ import ( "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth/legacy/legacytx" "github.com/cosmos/cosmos-sdk/x/evidence/exported" "github.com/cosmos/cosmos-sdk/x/evidence/types" ) @@ -50,8 +51,8 @@ func TestMsgSubmitEvidence(t *testing.T) { } for i, tc := range testCases { - require.Equal(t, tc.msg.Route(), types.RouterKey, "unexpected result for tc #%d", i) - require.Equal(t, tc.msg.Type(), types.TypeMsgSubmitEvidence, "unexpected result for tc #%d", i) + require.Equal(t, tc.msg.(legacytx.LegacyMsg).Route(), types.RouterKey, "unexpected result for tc #%d", i) + require.Equal(t, tc.msg.(legacytx.LegacyMsg).Type(), types.TypeMsgSubmitEvidence, "unexpected result for tc #%d", i) require.Equal(t, tc.expectErr, tc.msg.ValidateBasic() != nil, "unexpected result for tc #%d", i) if !tc.expectErr { diff --git a/x/feegrant/client/cli/tx.go b/x/feegrant/client/cli/tx.go index 2d38cd053082..e909a46999e8 100644 --- a/x/feegrant/client/cli/tx.go +++ b/x/feegrant/client/cli/tx.go @@ -58,7 +58,7 @@ Examples: %s tx %s grant cosmos1skjw... cosmos1skjw... --spend-limit 100stake --expiration 2022-01-30T15:04:05Z or %s tx %s grant cosmos1skjw... cosmos1skjw... --spend-limit 100stake --period 3600 --period-limit 10stake --expiration 36000 or %s tx %s grant cosmos1skjw... cosmos1skjw... --spend-limit 100stake --expiration 2022-01-30T15:04:05Z - --allowed-messages "/cosmos.gov.v1beta1.Msg/SubmitProposal,/cosmos.gov.v1beta1.Msg/Vote" + --allowed-messages "/cosmos.gov.v1beta1.MsgSubmitProposal,/cosmos.gov.v1beta1.MsgVote" `, version.AppName, types.ModuleName, version.AppName, types.ModuleName, version.AppName, types.ModuleName, ), ), diff --git a/x/feegrant/client/testutil/suite.go b/x/feegrant/client/testutil/suite.go index f1d1a70d4a79..7792bd8acf80 100644 --- a/x/feegrant/client/testutil/suite.go +++ b/x/feegrant/client/testutil/suite.go @@ -2,6 +2,7 @@ package testutil import ( "fmt" + "strings" "testing" "time" @@ -649,7 +650,7 @@ func (s *IntegrationTestSuite) TestFilteredFeeAllowance() { } spendLimit := sdk.NewCoin("stake", sdk.NewInt(1000)) - allowMsgs := "/cosmos.gov.v1beta1.Msg/SubmitProposal,weighted_vote" + allowMsgs := strings.Join([]string{sdk.MsgTypeURL(&govtypes.MsgSubmitProposal{}), sdk.MsgTypeURL(&govtypes.MsgVoteWeighted{})}, ",") testCases := []struct { name string diff --git a/x/feegrant/simulation/genesis.go b/x/feegrant/simulation/genesis.go index dee9b3b0fe5c..85fadcda4126 100644 --- a/x/feegrant/simulation/genesis.go +++ b/x/feegrant/simulation/genesis.go @@ -52,7 +52,7 @@ func generateRandomAllowances(granter, grantee sdk.AccAddress, r *rand.Rand) typ filteredAllowance, err := types.NewFeeAllowanceGrant(granter, grantee, &types.AllowedMsgFeeAllowance{ Allowance: basicAllowance.GetAllowance(), - AllowedMessages: []string{"/cosmos.gov.v1beta1.Msg/SubmitProposal"}, + AllowedMessages: []string{"/cosmos.gov.v1beta1.MsgSubmitProposal"}, }) if err != nil { panic(err) diff --git a/x/feegrant/simulation/operations.go b/x/feegrant/simulation/operations.go index f8c53a7092c9..b48ea9feb4d3 100644 --- a/x/feegrant/simulation/operations.go +++ b/x/feegrant/simulation/operations.go @@ -21,8 +21,11 @@ import ( const ( OpWeightMsgGrantFeeAllowance = "op_weight_msg_grant_fee_allowance" OpWeightMsgRevokeFeeAllowance = "op_weight_msg_grant_revoke_allowance" - TypeMsgGrantFeeAllowance = "/cosmos.feegrant.v1beta1.Msg/GrantFeeAllowance" - TypeMsgRevokeFeeAllowance = "/cosmos.feegrant.v1beta1.Msg/RevokeFeeAllowance" +) + +var ( + TypeMsgGrantFeeAllowance = sdk.MsgTypeURL(&types.MsgGrantFeeAllowance{}) + TypeMsgRevokeFeeAllowance = sdk.MsgTypeURL(&types.MsgRevokeFeeAllowance{}) ) func WeightedOperations( @@ -121,7 +124,7 @@ func SimulateMsgGrantFeeAllowance(ak types.AccountKeeper, bk types.BankKeeper, k _, _, err = app.Deliver(txGen.TxEncoder(), tx) if err != nil { - return simtypes.NoOpMsg(types.ModuleName, svcMsgClientConn.GetMsgs()[0].Type(), "unable to deliver tx"), nil, err + return simtypes.NoOpMsg(types.ModuleName, sdk.MsgTypeURL(svcMsgClientConn.GetMsgs()[0]), "unable to deliver tx"), nil, err } return simtypes.NewOperationMsg(svcMsgClientConn.GetMsgs()[0], true, "", protoCdc), nil, err } diff --git a/x/feegrant/types/codec.go b/x/feegrant/types/codec.go index 5557d96ac3d2..a8a0adb69508 100644 --- a/x/feegrant/types/codec.go +++ b/x/feegrant/types/codec.go @@ -8,7 +8,7 @@ import ( // RegisterInterfaces registers the interfaces types with the interface registry func RegisterInterfaces(registry types.InterfaceRegistry) { - registry.RegisterImplementations((*sdk.MsgRequest)(nil), + registry.RegisterImplementations((*sdk.Msg)(nil), &MsgGrantFeeAllowance{}, &MsgRevokeFeeAllowance{}, ) diff --git a/x/feegrant/types/filtered_fee.go b/x/feegrant/types/filtered_fee.go index 7fdbd0f21c5d..3cef6d2408b1 100644 --- a/x/feegrant/types/filtered_fee.go +++ b/x/feegrant/types/filtered_fee.go @@ -80,7 +80,7 @@ func (a *AllowedMsgFeeAllowance) allMsgTypesAllowed(ctx sdk.Context, msgs []sdk. for _, msg := range msgs { ctx.GasMeter().ConsumeGas(gasCostPerIteration, "check msg") - if !msgsMap[msg.Type()] { + if !msgsMap[sdk.MsgTypeURL(msg)] { return false } } diff --git a/x/feegrant/types/msgs.go b/x/feegrant/types/msgs.go index e346763f9200..9fb80cff8539 100644 --- a/x/feegrant/types/msgs.go +++ b/x/feegrant/types/msgs.go @@ -9,7 +9,7 @@ import ( ) var ( - _, _ sdk.MsgRequest = &MsgGrantFeeAllowance{}, &MsgRevokeFeeAllowance{} + _, _ sdk.Msg = &MsgGrantFeeAllowance{}, &MsgRevokeFeeAllowance{} _ types.UnpackInterfacesMessage = &MsgGrantFeeAllowance{} ) diff --git a/x/genutil/client/testutil/suite.go b/x/genutil/client/testutil/suite.go index a0bc047b4b4d..a1b077ab3022 100644 --- a/x/genutil/client/testutil/suite.go +++ b/x/genutil/client/testutil/suite.go @@ -15,6 +15,7 @@ import ( "github.com/cosmos/cosmos-sdk/testutil" "github.com/cosmos/cosmos-sdk/testutil/network" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth/legacy/legacytx" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" "github.com/cosmos/cosmos-sdk/x/genutil/client/cli" "github.com/cosmos/cosmos-sdk/x/staking/types" @@ -84,7 +85,7 @@ func (s *IntegrationTestSuite) TestGenTxCmd() { msgs := tx.GetMsgs() s.Require().Len(msgs, 1) - s.Require().Equal(types.TypeMsgCreateValidator, msgs[0].Type()) + s.Require().Equal(types.TypeMsgCreateValidator, msgs[0].(legacytx.LegacyMsg).Type()) s.Require().Equal([]sdk.AccAddress{val.Address}, msgs[0].GetSigners()) s.Require().Equal(amount, msgs[0].(*types.MsgCreateValidator).Value) err = tx.ValidateBasic() diff --git a/x/gov/client/utils/query.go b/x/gov/client/utils/query.go index 9b103e3468c9..c0734c0ff1dd 100644 --- a/x/gov/client/utils/query.go +++ b/x/gov/client/utils/query.go @@ -39,14 +39,14 @@ func (p Proposer) String() string { func QueryDepositsByTxQuery(clientCtx client.Context, params types.QueryProposalParams) ([]byte, error) { searchResult, err := combineEvents( clientCtx, defaultPage, - // Query old Msgs + // Query legacy Msgs event action []string{ fmt.Sprintf("%s.%s='%s'", sdk.EventTypeMessage, sdk.AttributeKeyAction, types.TypeMsgDeposit), fmt.Sprintf("%s.%s='%s'", types.EventTypeProposalDeposit, types.AttributeKeyProposalID, []byte(fmt.Sprintf("%d", params.ProposalID))), }, - // Query service Msgs + // Query proto Msgs event action []string{ - fmt.Sprintf("%s.%s='%s'", sdk.EventTypeMessage, sdk.AttributeKeyAction, types.TypeSvcMsgDeposit), + fmt.Sprintf("%s.%s='%s'", sdk.EventTypeMessage, sdk.AttributeKeyAction, sdk.MsgTypeURL(&types.MsgDeposit{})), fmt.Sprintf("%s.%s='%s'", types.EventTypeProposalDeposit, types.AttributeKeyProposalID, []byte(fmt.Sprintf("%d", params.ProposalID))), }, ) @@ -58,14 +58,7 @@ func QueryDepositsByTxQuery(clientCtx client.Context, params types.QueryProposal for _, info := range searchResult.Txs { for _, msg := range info.GetTx().GetMsgs() { - var depMsg *types.MsgDeposit - if msg.Type() == types.TypeSvcMsgDeposit { - depMsg = msg.(sdk.ServiceMsg).Request.(*types.MsgDeposit) - } else if protoDepMsg, ok := msg.(*types.MsgDeposit); ok { - depMsg = protoDepMsg - } - - if depMsg != nil { + if depMsg, ok := msg.(*types.MsgDeposit); ok { deposits = append(deposits, types.Deposit{ Depositor: depMsg.Depositor, ProposalId: params.ProposalID, @@ -95,27 +88,27 @@ func QueryVotesByTxQuery(clientCtx client.Context, params types.QueryProposalVot // query interrupted either if we collected enough votes or tx indexer run out of relevant txs for len(votes) < totalLimit { - // Search for both (old) votes and weighted votes. + // Search for both (legacy) votes and weighted votes. searchResult, err := combineEvents( clientCtx, nextTxPage, - // Query old Vote Msgs + // Query legacy Vote Msgs []string{ fmt.Sprintf("%s.%s='%s'", sdk.EventTypeMessage, sdk.AttributeKeyAction, types.TypeMsgVote), fmt.Sprintf("%s.%s='%s'", types.EventTypeProposalVote, types.AttributeKeyProposalID, []byte(fmt.Sprintf("%d", params.ProposalID))), }, - // Query Vote service Msgs + // Query Vote proto Msgs []string{ - fmt.Sprintf("%s.%s='%s'", sdk.EventTypeMessage, sdk.AttributeKeyAction, types.TypeSvcMsgVote), + fmt.Sprintf("%s.%s='%s'", sdk.EventTypeMessage, sdk.AttributeKeyAction, sdk.MsgTypeURL(&types.MsgVote{})), fmt.Sprintf("%s.%s='%s'", types.EventTypeProposalVote, types.AttributeKeyProposalID, []byte(fmt.Sprintf("%d", params.ProposalID))), }, - // Query old VoteWeighted Msgs + // Query legacy VoteWeighted Msgs []string{ fmt.Sprintf("%s.%s='%s'", sdk.EventTypeMessage, sdk.AttributeKeyAction, types.TypeMsgVoteWeighted), fmt.Sprintf("%s.%s='%s'", types.EventTypeProposalVote, types.AttributeKeyProposalID, []byte(fmt.Sprintf("%d", params.ProposalID))), }, - // Query VoteWeighted service Msgs + // Query VoteWeighted proto Msgs []string{ - fmt.Sprintf("%s.%s='%s'", sdk.EventTypeMessage, sdk.AttributeKeyAction, types.TypeSvcMsgVoteWeighted), + fmt.Sprintf("%s.%s='%s'", sdk.EventTypeMessage, sdk.AttributeKeyAction, sdk.MsgTypeURL(&types.MsgVoteWeighted{})), fmt.Sprintf("%s.%s='%s'", types.EventTypeProposalVote, types.AttributeKeyProposalID, []byte(fmt.Sprintf("%d", params.ProposalID))), }, ) @@ -125,14 +118,7 @@ func QueryVotesByTxQuery(clientCtx client.Context, params types.QueryProposalVot for _, info := range searchResult.Txs { for _, msg := range info.GetTx().GetMsgs() { - var voteMsg *types.MsgVote - if msg.Type() == types.TypeSvcMsgVote { - voteMsg = msg.(sdk.ServiceMsg).Request.(*types.MsgVote) - } else if protoVoteMsg, ok := msg.(*types.MsgVote); ok { - voteMsg = protoVoteMsg - } - - if voteMsg != nil { + if voteMsg, ok := msg.(*types.MsgVote); ok { votes = append(votes, types.Vote{ Voter: voteMsg.Voter, ProposalId: params.ProposalID, @@ -140,14 +126,7 @@ func QueryVotesByTxQuery(clientCtx client.Context, params types.QueryProposalVot }) } - var voteWeightedMsg *types.MsgVoteWeighted - if msg.Type() == types.TypeSvcMsgVoteWeighted { - voteWeightedMsg = msg.(sdk.ServiceMsg).Request.(*types.MsgVoteWeighted) - } else if protoVoteWeightedMsg, ok := msg.(*types.MsgVoteWeighted); ok { - voteWeightedMsg = protoVoteWeightedMsg - } - - if voteWeightedMsg != nil { + if voteWeightedMsg, ok := msg.(*types.MsgVoteWeighted); ok { votes = append(votes, types.Vote{ Voter: voteWeightedMsg.Voter, ProposalId: params.ProposalID, @@ -181,27 +160,27 @@ func QueryVotesByTxQuery(clientCtx client.Context, params types.QueryProposalVot func QueryVoteByTxQuery(clientCtx client.Context, params types.QueryVoteParams) ([]byte, error) { searchResult, err := combineEvents( clientCtx, defaultPage, - // Query old Vote Msgs + // Query legacy Vote Msgs []string{ fmt.Sprintf("%s.%s='%s'", sdk.EventTypeMessage, sdk.AttributeKeyAction, types.TypeMsgVote), fmt.Sprintf("%s.%s='%s'", types.EventTypeProposalVote, types.AttributeKeyProposalID, []byte(fmt.Sprintf("%d", params.ProposalID))), fmt.Sprintf("%s.%s='%s'", sdk.EventTypeMessage, sdk.AttributeKeySender, []byte(params.Voter.String())), }, - // Query Vote service Msgs + // Query Vote proto Msgs []string{ - fmt.Sprintf("%s.%s='%s'", sdk.EventTypeMessage, sdk.AttributeKeyAction, types.TypeSvcMsgVote), + fmt.Sprintf("%s.%s='%s'", sdk.EventTypeMessage, sdk.AttributeKeyAction, sdk.MsgTypeURL(&types.MsgVote{})), fmt.Sprintf("%s.%s='%s'", types.EventTypeProposalVote, types.AttributeKeyProposalID, []byte(fmt.Sprintf("%d", params.ProposalID))), fmt.Sprintf("%s.%s='%s'", sdk.EventTypeMessage, sdk.AttributeKeySender, []byte(params.Voter.String())), }, - // Query old VoteWeighted Msgs + // Query legacy VoteWeighted Msgs []string{ fmt.Sprintf("%s.%s='%s'", sdk.EventTypeMessage, sdk.AttributeKeyAction, types.TypeMsgVoteWeighted), fmt.Sprintf("%s.%s='%s'", types.EventTypeProposalVote, types.AttributeKeyProposalID, []byte(fmt.Sprintf("%d", params.ProposalID))), fmt.Sprintf("%s.%s='%s'", sdk.EventTypeMessage, sdk.AttributeKeySender, []byte(params.Voter.String())), }, - // Query VoteWeighted service Msgs + // Query VoteWeighted proto Msgs []string{ - fmt.Sprintf("%s.%s='%s'", sdk.EventTypeMessage, sdk.AttributeKeyAction, types.TypeSvcMsgVoteWeighted), + fmt.Sprintf("%s.%s='%s'", sdk.EventTypeMessage, sdk.AttributeKeyAction, sdk.MsgTypeURL(&types.MsgVoteWeighted{})), fmt.Sprintf("%s.%s='%s'", types.EventTypeProposalVote, types.AttributeKeyProposalID, []byte(fmt.Sprintf("%d", params.ProposalID))), fmt.Sprintf("%s.%s='%s'", sdk.EventTypeMessage, sdk.AttributeKeySender, []byte(params.Voter.String())), }, @@ -212,37 +191,26 @@ func QueryVoteByTxQuery(clientCtx client.Context, params types.QueryVoteParams) for _, info := range searchResult.Txs { for _, msg := range info.GetTx().GetMsgs() { - var voteMsg *types.MsgVote // there should only be a single vote under the given conditions - if msg.Type() == types.TypeSvcMsgVote { - voteMsg = msg.(sdk.ServiceMsg).Request.(*types.MsgVote) - } else if protoVoteMsg, ok := msg.(*types.MsgVote); ok { - voteMsg = protoVoteMsg - } - - if voteMsg != nil { - vote := types.Vote{ + var vote *types.Vote + if voteMsg, ok := msg.(*types.MsgVote); ok { + vote = &types.Vote{ Voter: voteMsg.Voter, ProposalId: params.ProposalID, Options: types.NewNonSplitVoteOption(voteMsg.Option), } + } - bz, err := clientCtx.JSONMarshaler.MarshalJSON(&vote) - if err != nil { - return nil, err - } - - return bz, nil - } else if msg.Type() == types.TypeMsgVoteWeighted { - voteMsg := msg.(*types.MsgVoteWeighted) - - vote := types.Vote{ - Voter: voteMsg.Voter, + if voteWeightedMsg, ok := msg.(*types.MsgVoteWeighted); ok { + vote = &types.Vote{ + Voter: voteWeightedMsg.Voter, ProposalId: params.ProposalID, - Options: voteMsg.Options, + Options: voteWeightedMsg.Options, } + } - bz, err := clientCtx.JSONMarshaler.MarshalJSON(&vote) + if vote != nil { + bz, err := clientCtx.JSONMarshaler.MarshalJSON(vote) if err != nil { return nil, err } @@ -260,15 +228,15 @@ func QueryVoteByTxQuery(clientCtx client.Context, params types.QueryVoteParams) func QueryDepositByTxQuery(clientCtx client.Context, params types.QueryDepositParams) ([]byte, error) { searchResult, err := combineEvents( clientCtx, defaultPage, - // Query old Msgs + // Query legacy Msgs event action []string{ fmt.Sprintf("%s.%s='%s'", sdk.EventTypeMessage, sdk.AttributeKeyAction, types.TypeMsgDeposit), fmt.Sprintf("%s.%s='%s'", types.EventTypeProposalDeposit, types.AttributeKeyProposalID, []byte(fmt.Sprintf("%d", params.ProposalID))), fmt.Sprintf("%s.%s='%s'", sdk.EventTypeMessage, sdk.AttributeKeySender, []byte(params.Depositor.String())), }, - // Query service Msgs + // Query proto Msgs event action []string{ - fmt.Sprintf("%s.%s='%s'", sdk.EventTypeMessage, sdk.AttributeKeyAction, types.TypeSvcMsgDeposit), + fmt.Sprintf("%s.%s='%s'", sdk.EventTypeMessage, sdk.AttributeKeyAction, sdk.MsgTypeURL(&types.MsgDeposit{})), fmt.Sprintf("%s.%s='%s'", types.EventTypeProposalDeposit, types.AttributeKeyProposalID, []byte(fmt.Sprintf("%d", params.ProposalID))), fmt.Sprintf("%s.%s='%s'", sdk.EventTypeMessage, sdk.AttributeKeySender, []byte(params.Depositor.String())), }, @@ -279,15 +247,8 @@ func QueryDepositByTxQuery(clientCtx client.Context, params types.QueryDepositPa for _, info := range searchResult.Txs { for _, msg := range info.GetTx().GetMsgs() { - var depMsg *types.MsgDeposit // there should only be a single deposit under the given conditions - if msg.Type() == types.TypeSvcMsgDeposit { - depMsg = msg.(sdk.ServiceMsg).Request.(*types.MsgDeposit) - } else if protoDepMsg, ok := msg.(*types.MsgDeposit); ok { - depMsg = protoDepMsg - } - - if depMsg != nil { + if depMsg, ok := msg.(*types.MsgDeposit); ok { deposit := types.Deposit{ Depositor: depMsg.Depositor, ProposalId: params.ProposalID, @@ -313,14 +274,14 @@ func QueryProposerByTxQuery(clientCtx client.Context, proposalID uint64) (Propos searchResult, err := combineEvents( clientCtx, defaultPage, - // Query old Msgs + // Query legacy Msgs event action []string{ fmt.Sprintf("%s.%s='%s'", sdk.EventTypeMessage, sdk.AttributeKeyAction, types.TypeMsgSubmitProposal), fmt.Sprintf("%s.%s='%s'", types.EventTypeSubmitProposal, types.AttributeKeyProposalID, []byte(fmt.Sprintf("%d", proposalID))), }, - // Query service Msgs + // Query proto Msgs event action []string{ - fmt.Sprintf("%s.%s='%s'", sdk.EventTypeMessage, sdk.AttributeKeyAction, types.TypeSvcMsgSubmitProposal), + fmt.Sprintf("%s.%s='%s'", sdk.EventTypeMessage, sdk.AttributeKeyAction, sdk.MsgTypeURL(&types.MsgSubmitProposal{})), fmt.Sprintf("%s.%s='%s'", types.EventTypeSubmitProposal, types.AttributeKeyProposalID, []byte(fmt.Sprintf("%d", proposalID))), }, ) @@ -331,13 +292,7 @@ func QueryProposerByTxQuery(clientCtx client.Context, proposalID uint64) (Propos for _, info := range searchResult.Txs { for _, msg := range info.GetTx().GetMsgs() { // there should only be a single proposal under the given conditions - if msg.Type() == types.TypeSvcMsgSubmitProposal { - subMsg := msg.(sdk.ServiceMsg).Request.(*types.MsgSubmitProposal) - - return NewProposer(proposalID, subMsg.Proposer), nil - } else if protoSubMsg, ok := msg.(*types.MsgSubmitProposal); ok { - subMsg := protoSubMsg - + if subMsg, ok := msg.(*types.MsgSubmitProposal); ok { return NewProposer(proposalID, subMsg.Proposer), nil } } @@ -367,7 +322,7 @@ func QueryProposalByID(proposalID uint64, clientCtx client.Context, queryRoute s // // Tx are indexed in tendermint via their Msgs `Type()`, which can be: // - via legacy Msgs (amino or proto), their `Type()` is a custom string, -// - via ADR-031 service msgs, their `Type()` is the protobuf FQ method name. +// - via ADR-031 proto msgs, their `Type()` is the protobuf FQ method name. // In searching for events, we search for both `Type()`s, and we use the // `combineEvents` function here to merge events. func combineEvents(clientCtx client.Context, page int, eventGroups ...[]string) (*sdk.SearchTxsResult, error) { diff --git a/x/gov/client/utils/query_test.go b/x/gov/client/utils/query_test.go index fb7d002c8583..30822c0d671c 100644 --- a/x/gov/client/utils/query_test.go +++ b/x/gov/client/utils/query_test.go @@ -13,6 +13,7 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/simapp" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth/legacy/legacytx" "github.com/cosmos/cosmos-sdk/x/gov/client/utils" "github.com/cosmos/cosmos-sdk/x/gov/types" ) @@ -44,7 +45,7 @@ func (mock TxSearchMock) TxSearch(ctx context.Context, query string, prove bool, return nil, err } for _, msg := range sdkTx.GetMsgs() { - if msg.Type() == msgType { + if msg.(legacytx.LegacyMsg).Type() == msgType { matchingTxs = append(matchingTxs, tx) break } diff --git a/x/gov/types/msgs.go b/x/gov/types/msgs.go index 098aad437857..f1c351e6ddca 100644 --- a/x/gov/types/msgs.go +++ b/x/gov/types/msgs.go @@ -18,12 +18,6 @@ const ( TypeMsgVote = "vote" TypeMsgVoteWeighted = "weighted_vote" TypeMsgSubmitProposal = "submit_proposal" - - // These are used for querying events by action. - TypeSvcMsgDeposit = "/cosmos.gov.v1beta1.Msg/Deposit" - TypeSvcMsgVote = "/cosmos.gov.v1beta1.Msg/Vote" - TypeSvcMsgVoteWeighted = "/cosmos.gov.v1beta1.Msg/VoteWeighted" - TypeSvcMsgSubmitProposal = "/cosmos.gov.v1beta1.Msg/SubmitProposal" ) var ( diff --git a/x/staking/client/rest/query.go b/x/staking/client/rest/query.go index 172ab477b7a7..b833766c2f91 100644 --- a/x/staking/client/rest/query.go +++ b/x/staking/client/rest/query.go @@ -153,28 +153,22 @@ func delegatorTxsHandlerFn(clientCtx client.Context) http.HandlerFunc { // For each case, we search txs for both: // - legacy messages: their Type() is a custom string, e.g. "delegate" - // - service Msgs: their Type() is their FQ method name, e.g. "/cosmos.staking.v1beta1.Msg/Delegate" + // - service Msgs: their Type() is their FQ method name, e.g. "/cosmos.staking.v1beta1.MsgDelegate" // and we combine the results. switch { case isBondTx: actions = append(actions, types.TypeMsgDelegate) - actions = append(actions, types.TypeSvcMsgDelegate) case isUnbondTx: actions = append(actions, types.TypeMsgUndelegate) - actions = append(actions, types.TypeSvcMsgUndelegate) case isRedTx: actions = append(actions, types.TypeMsgBeginRedelegate) - actions = append(actions, types.TypeSvcMsgBeginRedelegate) case noQuery: actions = append(actions, types.TypeMsgDelegate) - actions = append(actions, types.TypeSvcMsgDelegate) actions = append(actions, types.TypeMsgUndelegate) - actions = append(actions, types.TypeSvcMsgUndelegate) actions = append(actions, types.TypeMsgBeginRedelegate) - actions = append(actions, types.TypeSvcMsgBeginRedelegate) default: w.WriteHeader(http.StatusNoContent) diff --git a/x/staking/types/authz.go b/x/staking/types/authz.go index 32e8b719d1f2..45e0e4088d11 100644 --- a/x/staking/types/authz.go +++ b/x/staking/types/authz.go @@ -12,10 +12,6 @@ const gasCostPerIteration = uint64(10) var ( _ authz.Authorization = &StakeAuthorization{} - - TypeDelegate = "/cosmos.staking.v1beta1.Msg/Delegate" - TypeUndelegate = "/cosmos.staking.v1beta1.Msg/Undelegate" - TypeBeginRedelegate = "/cosmos.staking.v1beta1.Msg/BeginRedelegate" ) // NewStakeAuthorization creates a new StakeAuthorization object. @@ -61,11 +57,11 @@ func (authorization StakeAuthorization) ValidateBasic() error { } // Accept implements Authorization.Accept. -func (authorization StakeAuthorization) Accept(ctx sdk.Context, msg sdk.ServiceMsg) (updated authz.Authorization, delete bool, err error) { +func (authorization StakeAuthorization) Accept(ctx sdk.Context, msg sdk.Msg) (updated authz.Authorization, delete bool, err error) { var validatorAddress string var amount sdk.Coin - switch msg := msg.Request.(type) { + switch msg := msg.(type) { case *MsgDelegate: validatorAddress = msg.ValidatorAddress amount = msg.Amount @@ -142,11 +138,11 @@ func validateAndBech32fy(allowed []sdk.ValAddress, denied []sdk.ValAddress) ([]s func normalizeAuthzType(authzType AuthorizationType) (string, error) { switch authzType { case AuthorizationType_AUTHORIZATION_TYPE_DELEGATE: - return TypeDelegate, nil + return sdk.MsgTypeURL(&MsgDelegate{}), nil case AuthorizationType_AUTHORIZATION_TYPE_UNDELEGATE: - return TypeUndelegate, nil + return sdk.MsgTypeURL(&MsgUndelegate{}), nil case AuthorizationType_AUTHORIZATION_TYPE_REDELEGATE: - return TypeBeginRedelegate, nil + return sdk.MsgTypeURL(&MsgBeginRedelegate{}), nil default: return "", sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "unknown authorization type %T", authzType) } diff --git a/x/staking/types/authz_test.go b/x/staking/types/authz_test.go index c43ef9e1fb48..31b95b702283 100644 --- a/x/staking/types/authz_test.go +++ b/x/staking/types/authz_test.go @@ -3,9 +3,8 @@ package types_test import ( "testing" - tmproto "github.com/tendermint/tendermint/proto/tendermint/types" - "github.com/stretchr/testify/require" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" "github.com/cosmos/cosmos-sdk/simapp" sdk "github.com/cosmos/cosmos-sdk/types" @@ -33,7 +32,7 @@ func TestAuthzAuthorizations(t *testing.T) { // verify MethodName delAuth, err = stakingtypes.NewStakeAuthorization([]sdk.ValAddress{val1, val2}, []sdk.ValAddress{}, stakingtypes.AuthorizationType_AUTHORIZATION_TYPE_DELEGATE, &coin100) require.NoError(t, err) - require.Equal(t, delAuth.MethodName(), stakingtypes.TypeDelegate) + require.Equal(t, delAuth.MethodName(), sdk.MsgTypeURL(&stakingtypes.MsgDelegate{})) // error both allow & deny list _, err = stakingtypes.NewStakeAuthorization([]sdk.ValAddress{val1, val2}, []sdk.ValAddress{val1}, stakingtypes.AuthorizationType_AUTHORIZATION_TYPE_DELEGATE, &coin100) @@ -41,11 +40,11 @@ func TestAuthzAuthorizations(t *testing.T) { // verify MethodName undelAuth, _ := stakingtypes.NewStakeAuthorization([]sdk.ValAddress{val1, val2}, []sdk.ValAddress{}, stakingtypes.AuthorizationType_AUTHORIZATION_TYPE_UNDELEGATE, &coin100) - require.Equal(t, undelAuth.MethodName(), stakingtypes.TypeUndelegate) + require.Equal(t, undelAuth.MethodName(), sdk.MsgTypeURL(&stakingtypes.MsgUndelegate{})) // verify MethodName beginRedelAuth, _ := stakingtypes.NewStakeAuthorization([]sdk.ValAddress{val1, val2}, []sdk.ValAddress{}, stakingtypes.AuthorizationType_AUTHORIZATION_TYPE_REDELEGATE, &coin100) - require.Equal(t, beginRedelAuth.MethodName(), stakingtypes.TypeBeginRedelegate) + require.Equal(t, beginRedelAuth.MethodName(), sdk.MsgTypeURL(&stakingtypes.MsgBeginRedelegate{})) validators1_2 := []string{val1.String(), val2.String()} @@ -55,7 +54,7 @@ func TestAuthzAuthorizations(t *testing.T) { denied []sdk.ValAddress msgType stakingtypes.AuthorizationType limit *sdk.Coin - srvMsg sdk.ServiceMsg + srvMsg sdk.Msg expectErr bool isDelete bool updatedAuthorization *stakingtypes.StakeAuthorization @@ -66,7 +65,7 @@ func TestAuthzAuthorizations(t *testing.T) { []sdk.ValAddress{}, stakingtypes.AuthorizationType_AUTHORIZATION_TYPE_DELEGATE, &coin100, - createSrvMsgDelegate(delAuth.MethodName(), delAddr, val1, coin100), + stakingtypes.NewMsgDelegate(delAddr, val1, coin100), false, true, nil, @@ -77,7 +76,7 @@ func TestAuthzAuthorizations(t *testing.T) { []sdk.ValAddress{}, stakingtypes.AuthorizationType_AUTHORIZATION_TYPE_DELEGATE, &coin100, - createSrvMsgDelegate(delAuth.MethodName(), delAddr, val1, coin50), + stakingtypes.NewMsgDelegate(delAddr, val1, coin50), false, false, &stakingtypes.StakeAuthorization{ @@ -91,7 +90,7 @@ func TestAuthzAuthorizations(t *testing.T) { []sdk.ValAddress{}, stakingtypes.AuthorizationType_AUTHORIZATION_TYPE_DELEGATE, &coin100, - createSrvMsgDelegate(delAuth.MethodName(), delAddr, val3, coin100), + stakingtypes.NewMsgDelegate(delAddr, val3, coin100), true, false, nil, @@ -102,7 +101,7 @@ func TestAuthzAuthorizations(t *testing.T) { []sdk.ValAddress{}, stakingtypes.AuthorizationType_AUTHORIZATION_TYPE_DELEGATE, nil, - createSrvMsgDelegate(delAuth.MethodName(), delAddr, val2, coin100), + stakingtypes.NewMsgDelegate(delAddr, val2, coin100), false, false, &stakingtypes.StakeAuthorization{ @@ -116,7 +115,7 @@ func TestAuthzAuthorizations(t *testing.T) { []sdk.ValAddress{val1}, stakingtypes.AuthorizationType_AUTHORIZATION_TYPE_DELEGATE, nil, - createSrvMsgDelegate(delAuth.MethodName(), delAddr, val1, coin100), + stakingtypes.NewMsgDelegate(delAddr, val1, coin100), true, false, nil, @@ -128,7 +127,7 @@ func TestAuthzAuthorizations(t *testing.T) { []sdk.ValAddress{}, stakingtypes.AuthorizationType_AUTHORIZATION_TYPE_UNDELEGATE, &coin100, - createSrvMsgUndelegate(undelAuth.MethodName(), delAddr, val1, coin100), + stakingtypes.NewMsgUndelegate(delAddr, val1, coin100), false, true, nil, @@ -139,7 +138,7 @@ func TestAuthzAuthorizations(t *testing.T) { []sdk.ValAddress{}, stakingtypes.AuthorizationType_AUTHORIZATION_TYPE_UNDELEGATE, &coin100, - createSrvMsgUndelegate(undelAuth.MethodName(), delAddr, val1, coin50), + stakingtypes.NewMsgUndelegate(delAddr, val1, coin50), false, false, &stakingtypes.StakeAuthorization{ @@ -153,7 +152,7 @@ func TestAuthzAuthorizations(t *testing.T) { []sdk.ValAddress{}, stakingtypes.AuthorizationType_AUTHORIZATION_TYPE_UNDELEGATE, &coin100, - createSrvMsgUndelegate(undelAuth.MethodName(), delAddr, val3, coin100), + stakingtypes.NewMsgUndelegate(delAddr, val3, coin100), true, false, nil, @@ -164,7 +163,7 @@ func TestAuthzAuthorizations(t *testing.T) { []sdk.ValAddress{}, stakingtypes.AuthorizationType_AUTHORIZATION_TYPE_UNDELEGATE, nil, - createSrvMsgUndelegate(undelAuth.MethodName(), delAddr, val2, coin100), + stakingtypes.NewMsgUndelegate(delAddr, val2, coin100), false, false, &stakingtypes.StakeAuthorization{ @@ -178,7 +177,7 @@ func TestAuthzAuthorizations(t *testing.T) { []sdk.ValAddress{val1}, stakingtypes.AuthorizationType_AUTHORIZATION_TYPE_UNDELEGATE, &coin100, - createSrvMsgUndelegate(undelAuth.MethodName(), delAddr, val1, coin100), + stakingtypes.NewMsgUndelegate(delAddr, val1, coin100), true, false, nil, @@ -190,7 +189,7 @@ func TestAuthzAuthorizations(t *testing.T) { []sdk.ValAddress{}, stakingtypes.AuthorizationType_AUTHORIZATION_TYPE_REDELEGATE, &coin100, - createSrvMsgUndelegate(undelAuth.MethodName(), delAddr, val1, coin100), + stakingtypes.NewMsgUndelegate(delAddr, val1, coin100), false, true, nil, @@ -201,7 +200,7 @@ func TestAuthzAuthorizations(t *testing.T) { []sdk.ValAddress{}, stakingtypes.AuthorizationType_AUTHORIZATION_TYPE_REDELEGATE, &coin100, - createSrvMsgReDelegate(undelAuth.MethodName(), delAddr, val1, coin50), + stakingtypes.NewMsgBeginRedelegate(delAddr, val1, val1, coin50), false, false, &stakingtypes.StakeAuthorization{ @@ -215,7 +214,7 @@ func TestAuthzAuthorizations(t *testing.T) { []sdk.ValAddress{}, stakingtypes.AuthorizationType_AUTHORIZATION_TYPE_REDELEGATE, &coin100, - createSrvMsgReDelegate(undelAuth.MethodName(), delAddr, val3, coin100), + stakingtypes.NewMsgBeginRedelegate(delAddr, val3, val3, coin100), true, false, nil, @@ -226,7 +225,7 @@ func TestAuthzAuthorizations(t *testing.T) { []sdk.ValAddress{}, stakingtypes.AuthorizationType_AUTHORIZATION_TYPE_REDELEGATE, nil, - createSrvMsgReDelegate(undelAuth.MethodName(), delAddr, val2, coin100), + stakingtypes.NewMsgBeginRedelegate(delAddr, val2, val2, coin100), false, false, &stakingtypes.StakeAuthorization{ @@ -240,7 +239,7 @@ func TestAuthzAuthorizations(t *testing.T) { []sdk.ValAddress{val1}, stakingtypes.AuthorizationType_AUTHORIZATION_TYPE_REDELEGATE, &coin100, - createSrvMsgReDelegate(undelAuth.MethodName(), delAddr, val1, coin100), + stakingtypes.NewMsgBeginRedelegate(delAddr, val1, val1, coin100), true, false, nil, @@ -266,27 +265,3 @@ func TestAuthzAuthorizations(t *testing.T) { }) } } - -func createSrvMsgUndelegate(methodName string, delAddr sdk.AccAddress, valAddr sdk.ValAddress, amount sdk.Coin) sdk.ServiceMsg { - msg := stakingtypes.NewMsgUndelegate(delAddr, valAddr, amount) - return sdk.ServiceMsg{ - MethodName: methodName, - Request: msg, - } -} - -func createSrvMsgReDelegate(methodName string, delAddr sdk.AccAddress, valAddr sdk.ValAddress, amount sdk.Coin) sdk.ServiceMsg { - msg := stakingtypes.NewMsgBeginRedelegate(delAddr, valAddr, valAddr, amount) - return sdk.ServiceMsg{ - MethodName: methodName, - Request: msg, - } -} - -func createSrvMsgDelegate(methodName string, delAddr sdk.AccAddress, valAddr sdk.ValAddress, amount sdk.Coin) sdk.ServiceMsg { - msg := stakingtypes.NewMsgDelegate(delAddr, valAddr, amount) - return sdk.ServiceMsg{ - MethodName: methodName, - Request: msg, - } -} diff --git a/x/staking/types/msg.go b/x/staking/types/msg.go index e397046e5779..2525aa66468f 100644 --- a/x/staking/types/msg.go +++ b/x/staking/types/msg.go @@ -16,13 +16,6 @@ const ( TypeMsgCreateValidator = "create_validator" TypeMsgDelegate = "delegate" TypeMsgBeginRedelegate = "begin_redelegate" - - // These are used for querying events by action. - TypeSvcMsgUndelegate = "/cosmos.staking.v1beta1.Msg/Undelegate" - TypeSvcMsgEditValidator = "/cosmos.staking.v1beta1.Msg/EditValidator" - TypeSvcMsgCreateValidator = "/cosmos.staking.v1beta1.Msg/CreateValidator" - TypeSvcMsgDelegate = "/cosmos.staking.v1beta1.Msg/Delegate" - TypeSvcMsgBeginRedelegate = "/cosmos.staking.v1beta1.Msg/BeginRedelegate" ) var (