Remove ServiceMsgs from ADR-031 (#9139)

* wip

* wip

* wip

* wip on refactoring adr 031 type URLs

* Fix msg_service_router

* Fix gov client queries

* Fix some modules tests

* Remove all instances of "*.Msg/*"

* Uncomment code

* Remove commented code

* // simulation.NewWeightedOperation(

* Fix CopyTx

* Fix more tests

* Fix x/gov test

* proto.MessageName->sdk.MsgName

* Fix authz tests

* Use MsgRoute in feegrant and staking/authz

* Fix more tests

* Fix sims?

* Add norace tag

* Add CL

* rebuild rosetta api test data

* Update ADR

* Rename MsgRoute -> MsgTypeURL

* Fix codec registration

* Remove sdk.GetLegacySignBytes

* Update types/tx_msg.go

* Update x/authz/simulation/operations.go

* Move LegacyMsg to legacytx

* Update CHANGELOG.md

Co-authored-by: Aaron Craelius <aaron@regen.network>

* Remove NewAnyWithCustomTypeURL

* Keep support for ServiceMsgs

* Fix TxBody UnpackInterfaces

* Fix test

* Address review

* Remove support for ServiceMsg typeURLs

* Fix lint

* Update changelog

* Fix tests

* Use sdk.MsgTypeURL everywhere

* Fix tests

* Fix rosetta, run make rosetta-data

* Fix rosetta thanks to froydi

* Address reviews

* Fix test

* Remove stray log

* Update CL

Co-authored-by: Aaron Craelius <aaronc@users.noreply.github.com>
Co-authored-by: Alessio Treglia <alessio@tendermint.com>
Co-authored-by: Aaron Craelius <aaron@regen.network>
This commit is contained in:
Amaury
2021-04-30 11:00:47 +00:00
committed by GitHub
co-authored by Aaron Craelius Aaron Craelius Alessio Treglia
parent 6fbded9664
commit dfe3e7a8d7
62 changed files with 428 additions and 903 deletions
-5
View File
@@ -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))
}
+3 -10
View File
@@ -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
}
+4 -7
View File
@@ -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
}
-70
View File
@@ -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
}
+8 -11
View File
@@ -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
+8 -28
View File
@@ -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
}
}
+7 -11
View File
@@ -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))
}