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:
co-authored by
Aaron Craelius
Aaron Craelius
Alessio Treglia
parent
6fbded9664
commit
dfe3e7a8d7
@@ -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,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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
@@ -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
@@ -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))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user