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:
Amaury Martiny
2020-10-15 13:07:59 +00:00
committed by GitHub
co-authored by Aaron Craelius Aleksandr Bezobchuk Marie Gauthier Aaron Craelius
parent e6e4a94071
commit 55242a659c
49 changed files with 5274 additions and 3850 deletions
+3
View File
@@ -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))
}
+58
View File
@@ -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
View File
@@ -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
View File
@@ -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
}