Add ADR 031 BaseApp and codec infrastructure (#7519)
* Refactor RegisterQueryServices -> RegisterServices * Cleaner proto files * Fix tests * Add MsgServer * Fix lint * Remove MsgServer from configurator for now * Remove useless file * Fix build * typo * Add router * Fix test * WIP * Add router * Remove test helper * Add beginning of test * Move test to simapp? * ServiceMsg implement sdk.Msg * Add handler by MsgServiceRouter * Correct signature * Add full test * use TxEncoder * Update baseapp/msg_service_router.go Co-authored-by: Aaron Craelius <aaron@regen.network> * Push changes * WIP on ServiceMsg unpacking * Make TestMsgService test pass * Fix tests * Tidying up * Tidying up * Tidying up * Add JSON test * Add comments * Tidying * Lint * Register MsgRequest interface * Rename * Fix tests * RegisterCustomTypeURL * Add changelog entries * Put in features * Update baseapp/msg_service_router.go Co-authored-by: Aleksandr Bezobchuk <alexanderbez@users.noreply.github.com> * Update baseapp/msg_service_router.go Co-authored-by: Aleksandr Bezobchuk <alexanderbez@users.noreply.github.com> * Update baseapp/msg_service_router.go Co-authored-by: Aleksandr Bezobchuk <alexanderbez@users.noreply.github.com> * Update baseapp/msg_service_router.go Co-authored-by: Aleksandr Bezobchuk <alexanderbez@users.noreply.github.com> * Update baseapp/msg_service_router.go Co-authored-by: Aleksandr Bezobchuk <alexanderbez@users.noreply.github.com> * Update baseapp/msg_service_router.go Co-authored-by: Aleksandr Bezobchuk <alexanderbez@users.noreply.github.com> * Update baseapp/msg_service_router.go Co-authored-by: Aleksandr Bezobchuk <alexanderbez@users.noreply.github.com> * Address review comments * Address nit * Fix lint * Update codec/types/interface_registry.go Co-authored-by: Marie Gauthier <marie.gauthier63@gmail.com> * godoc Co-authored-by: Aaron Craelius <aaronc@users.noreply.github.com> Co-authored-by: Aaron Craelius <aaron@regen.network> Co-authored-by: Aleksandr Bezobchuk <alexanderbez@users.noreply.github.com> Co-authored-by: Marie Gauthier <marie.gauthier63@gmail.com>
This commit is contained in:
co-authored by
Aaron Craelius
Aleksandr Bezobchuk
Marie Gauthier
Aaron Craelius
parent
e6e4a94071
commit
55242a659c
@@ -14,4 +14,7 @@ func RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {
|
||||
// RegisterInterfaces registers the sdk message type.
|
||||
func RegisterInterfaces(registry types.InterfaceRegistry) {
|
||||
registry.RegisterInterface("cosmos.base.v1beta1.Msg", (*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("cosmos.base.v1beta1.ServiceMsg", (*MsgRequest)(nil))
|
||||
}
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"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.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 {
|
||||
panic("ServiceMsg does not have a GetSignBytes method")
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
+4
-3
@@ -5,6 +5,10 @@ package tx
|
||||
|
||||
import (
|
||||
fmt "fmt"
|
||||
io "io"
|
||||
math "math"
|
||||
math_bits "math/bits"
|
||||
|
||||
types "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
types1 "github.com/cosmos/cosmos-sdk/crypto/types"
|
||||
github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types"
|
||||
@@ -12,9 +16,6 @@ import (
|
||||
signing "github.com/cosmos/cosmos-sdk/types/tx/signing"
|
||||
_ "github.com/gogo/protobuf/gogoproto"
|
||||
proto "github.com/gogo/protobuf/proto"
|
||||
io "io"
|
||||
math "math"
|
||||
math_bits "math/bits"
|
||||
)
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
|
||||
+32
-6
@@ -1,7 +1,8 @@
|
||||
package tx
|
||||
|
||||
import (
|
||||
fmt "fmt"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
|
||||
@@ -26,7 +27,15 @@ func (t *Tx) GetMsgs() []sdk.Msg {
|
||||
anys := t.Body.Messages
|
||||
res := make([]sdk.Msg, len(anys))
|
||||
for i, any := range anys {
|
||||
msg := any.GetCachedValue().(sdk.Msg)
|
||||
var msg sdk.Msg
|
||||
if isServiceMsg(any.TypeUrl) {
|
||||
msg = sdk.ServiceMsg{
|
||||
MethodName: any.TypeUrl,
|
||||
Request: any.GetCachedValue().(sdk.MsgRequest),
|
||||
}
|
||||
} else {
|
||||
msg = any.GetCachedValue().(sdk.Msg)
|
||||
}
|
||||
res[i] = msg
|
||||
}
|
||||
return res
|
||||
@@ -138,12 +147,23 @@ 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 {
|
||||
var msg sdk.Msg
|
||||
err := unpacker.UnpackAny(any, &msg)
|
||||
if err != nil {
|
||||
return err
|
||||
// If the any's typeUrl contains 2 slashes, then we unpack the any into
|
||||
// a ServiceMsg struct as per ADR-031.
|
||||
if 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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -168,3 +188,9 @@ func RegisterInterfaces(registry codectypes.InterfaceRegistry) {
|
||||
registry.RegisterInterface("cosmos.tx.v1beta1.Tx", (*sdk.Tx)(nil))
|
||||
registry.RegisterImplementations((*sdk.Tx)(nil), &Tx{})
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user