From b9e65b6d418e4b7601f63fa01fe96e3d845dd2e9 Mon Sep 17 00:00:00 2001 From: Aaron Craelius Date: Tue, 1 Nov 2022 17:34:59 -0400 Subject: [PATCH] feat: add autocli app wiring + remote info support (#13281) --- client/tx/factory.go | 3 +- client/tx/tx_test.go | 1 + client/v2/autocli/interface.go | 32 ++++++ client/v2/go.mod | 4 + client/v2/go.sum | 19 ++++ runtime/app.go | 14 ++- runtime/internal/services/app.go | 23 ++++ runtime/internal/services/autocli.go | 37 +++++++ runtime/internal/services/reflection.go | 73 +++++++++++++ runtime/module.go | 5 + runtime/services.go | 22 ++++ simapp/simd/cmd/root.go | 1 + tests/go.mod | 4 +- tests/go.sum | 2 + tests/integration/runtime/query_test.go | 134 ++++++++++++++++++++++++ x/auth/module.go | 31 +++++- x/auth/types/account_test.go | 1 + x/auth/types/autocli.go | 26 +++++ x/auth/vesting/module.go | 2 + x/capability/module.go | 1 + x/evidence/module.go | 2 + 21 files changed, 429 insertions(+), 8 deletions(-) create mode 100644 client/v2/autocli/interface.go create mode 100644 runtime/internal/services/app.go create mode 100644 runtime/internal/services/autocli.go create mode 100644 runtime/internal/services/reflection.go create mode 100644 runtime/services.go create mode 100644 tests/integration/runtime/query_test.go create mode 100644 x/auth/types/autocli.go diff --git a/client/tx/factory.go b/client/tx/factory.go index c6d781bb4abe..3d174c0e8946 100644 --- a/client/tx/factory.go +++ b/client/tx/factory.go @@ -9,6 +9,8 @@ import ( "cosmossdk.io/math" "github.com/spf13/pflag" + "github.com/cosmos/go-bip39" + "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/crypto/keyring" @@ -17,7 +19,6 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/tx" "github.com/cosmos/cosmos-sdk/types/tx/signing" - "github.com/cosmos/go-bip39" ) // Factory defines a client transaction factory that facilitates generating and diff --git a/client/tx/tx_test.go b/client/tx/tx_test.go index acdff64f8324..9c687a42ebb1 100644 --- a/client/tx/tx_test.go +++ b/client/tx/tx_test.go @@ -10,6 +10,7 @@ import ( "google.golang.org/grpc" "cosmossdk.io/depinject" + "github.com/cosmos/cosmos-sdk/client" clienttestutil "github.com/cosmos/cosmos-sdk/client/testutil" "github.com/cosmos/cosmos-sdk/client/tx" diff --git a/client/v2/autocli/interface.go b/client/v2/autocli/interface.go new file mode 100644 index 000000000000..edcb5226094f --- /dev/null +++ b/client/v2/autocli/interface.go @@ -0,0 +1,32 @@ +package autocli + +import ( + autocliv1 "cosmossdk.io/api/cosmos/autocli/v1" + "github.com/spf13/cobra" + + "cosmossdk.io/core/appmodule" +) + +// HasAutoCLIConfig is an AppModule extension interface for declaring autocli module options. +type HasAutoCLIConfig interface { + appmodule.AppModule + + // AutoCLIOptions are the autocli module options for this module. + AutoCLIOptions() *autocliv1.ModuleOptions +} + +// HasCustomQueryCommand is an AppModule extension interface for declaring a custom query command. +type HasCustomQueryCommand interface { + appmodule.AppModule + + // GetQueryCmd returns a custom cobra query command for this module. + GetQueryCmd() *cobra.Command +} + +// HasCustomTxCommand is an AppModule extension interface for declaring a custom tx command. +type HasCustomTxCommand interface { + appmodule.AppModule + + // GetTxCmd returns a custom cobra tx command for this module. + GetTxCmd() *cobra.Command +} diff --git a/client/v2/go.mod b/client/v2/go.mod index 6e8a2550c7e1..d984af3986d4 100644 --- a/client/v2/go.mod +++ b/client/v2/go.mod @@ -4,6 +4,7 @@ go 1.19 require ( cosmossdk.io/api v0.2.4 + cosmossdk.io/core v0.3.2 github.com/cosmos/cosmos-proto v1.0.0-alpha8 github.com/iancoleman/strcase v0.2.0 github.com/spf13/cobra v1.6.1 @@ -14,10 +15,13 @@ require ( ) require ( + cosmossdk.io/depinject v1.0.0-alpha.3 // indirect github.com/cosmos/gogoproto v1.4.2 // indirect github.com/golang/protobuf v1.5.2 // indirect github.com/google/go-cmp v0.5.9 // indirect github.com/inconshreveable/mousetrap v1.0.1 // indirect + github.com/pkg/errors v0.9.1 // indirect + golang.org/x/exp v0.0.0-20221019170559-20944726eadf // indirect golang.org/x/net v0.0.0-20221017152216-f25eb7ecb193 // indirect golang.org/x/sys v0.0.0-20221013171732-95e765b1cc43 // indirect golang.org/x/text v0.3.8 // indirect diff --git a/client/v2/go.sum b/client/v2/go.sum index 7e4f2f724338..35c15f58501a 100644 --- a/client/v2/go.sum +++ b/client/v2/go.sum @@ -1,10 +1,20 @@ cosmossdk.io/api v0.2.4 h1:o2t77GXWWEN5egCzD2ZyyFgbsoAif/XdF3T+/sAYiHQ= cosmossdk.io/api v0.2.4/go.mod h1:7xfxe8ghXHoKj3W2oG/HcuxGVwUHN3q8piiIEiJ3CEU= +cosmossdk.io/core v0.3.2 h1:KlQIufpJHJvOs7YLGTZsZcCo1WlkencDXepsr8STKZQ= +cosmossdk.io/core v0.3.2/go.mod h1:CO7vbe+evrBvHc0setFHL/u7nlY7HJGzdRSBkT/sirc= +cosmossdk.io/depinject v1.0.0-alpha.3 h1:6evFIgj//Y3w09bqOUOzEpFj5tsxBqdc5CfkO7z+zfw= +cosmossdk.io/depinject v1.0.0-alpha.3/go.mod h1:eRbcdQ7MRpIPEM5YUJh8k97nxHpYbc3sMUnEtt8HPWU= +github.com/alecthomas/participle/v2 v2.0.0-alpha7 h1:cK4vjj0VSgb3lN1nuKA5F7dw+1s1pWBe5bx7nNCnN+c= +github.com/cockroachdb/apd/v3 v3.1.0 h1:MK3Ow7LH0W8zkd5GMKA1PvS9qG3bWFI95WaVNfyZJ/w= github.com/cosmos/cosmos-proto v1.0.0-alpha8 h1:d3pCRuMYYvGA5bM0ZbbjKn+AoQD4A7dyNG2wzwWalUw= github.com/cosmos/cosmos-proto v1.0.0-alpha8/go.mod h1:6/p+Bc4O8JKeZqe0VqUGTX31eoYqemTT4C1hLCWsO7I= github.com/cosmos/gogoproto v1.4.2 h1:UeGRcmFW41l0G0MiefWhkPEVEwvu78SZsHBvI78dAYw= github.com/cosmos/gogoproto v1.4.2/go.mod h1:cLxOsn1ljAHSV527CHOtaIP91kK6cCrZETRBrkzItWU= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cucumber/common/gherkin/go/v22 v22.0.0 h1:4K8NqptbvdOrjL9DEea6HFjSpbdT9+Q5kgLpmmsHYl0= +github.com/cucumber/common/messages/go/v17 v17.1.1 h1:RNqopvIFyLWnKv0LfATh34SWBhXeoFTJnSrgm9cT/Ts= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/gofrs/uuid v4.2.0+incompatible h1:yyYWMnhkhrKwwr8gAOcOCYxOOscHgDS9yZgBrnJfGa0= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= @@ -15,15 +25,22 @@ github.com/iancoleman/strcase v0.2.0 h1:05I4QRnGpI0m37iZQRuskXh+w77mr6Z41lwQzuHL github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc= github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/regen-network/gocuke v0.6.2 h1:pHviZ0kKAq2U2hN2q3smKNxct6hS0mGByFMHGnWA97M= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA= github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/exp v0.0.0-20221019170559-20944726eadf h1:nFVjjKDgNY37+ZSYCJmtYf7tOlfQswHqplG2eosjOMg= +golang.org/x/exp v0.0.0-20221019170559-20944726eadf/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -58,6 +75,8 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools/v3 v3.4.0 h1:ZazjZUfuVeZGLAmlKKuyv3IKP5orXcwtOwDQH6YVr6o= gotest.tools/v3 v3.4.0/go.mod h1:CtbdzLSsqVhDgMtKsx03ird5YTGB3ar27v0u/yKBW5g= +pgregory.net/rapid v0.5.3 h1:163N50IHFqr1phZens4FQOdPgfJscR7a562mjQqeo4M= diff --git a/runtime/app.go b/runtime/app.go index 5cc714e8ade6..427b03f6f0c9 100644 --- a/runtime/app.go +++ b/runtime/app.go @@ -4,10 +4,14 @@ import ( "encoding/json" "fmt" - runtimev1alpha1 "cosmossdk.io/api/cosmos/app/runtime/v1alpha1" abci "github.com/tendermint/tendermint/abci/types" "golang.org/x/exp/slices" + runtimev1alpha1 "cosmossdk.io/api/cosmos/app/runtime/v1alpha1" + "cosmossdk.io/core/appmodule" + + appv1alpha1 "cosmossdk.io/api/cosmos/app/v1alpha1" + "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/client" nodeservice "github.com/cosmos/cosmos-sdk/client/grpc/node" @@ -49,6 +53,8 @@ type App struct { endBlockers []func(sdk.Context, abci.RequestEndBlock) []abci.ValidatorUpdate baseAppOptions []BaseAppOption msgServiceRouter *baseapp.MsgServiceRouter + appConfig *appv1alpha1.Config + appModules map[string]appmodule.AppModule } // RegisterModules registers the provided modules with the module manager and @@ -76,6 +82,12 @@ func (a *App) RegisterModules(modules ...module.AppModule) error { // Load finishes all initialization operations and loads the app. func (a *App) Load(loadLatest bool) error { + // register runtime module services + err := a.registerRuntimeServices() + if err != nil { + return err + } + a.configurator = module.NewConfigurator(a.cdc, a.MsgServiceRouter(), a.GRPCQueryRouter()) a.ModuleManager.RegisterServices(a.configurator) diff --git a/runtime/internal/services/app.go b/runtime/internal/services/app.go new file mode 100644 index 000000000000..fa80a281025e --- /dev/null +++ b/runtime/internal/services/app.go @@ -0,0 +1,23 @@ +package services + +import ( + "context" + + appv1alpha1 "cosmossdk.io/api/cosmos/app/v1alpha1" +) + +// AppQueryService implements the cosmos.app.v1alpha1.Query service +type AppQueryService struct { + appv1alpha1.UnimplementedQueryServer + appConfig *appv1alpha1.Config +} + +func NewAppQueryService(appConfig *appv1alpha1.Config) *AppQueryService { + return &AppQueryService{appConfig: appConfig} +} + +func (a *AppQueryService) Config(context.Context, *appv1alpha1.QueryConfigRequest) (*appv1alpha1.QueryConfigResponse, error) { + return &appv1alpha1.QueryConfigResponse{Config: a.appConfig}, nil +} + +var _ appv1alpha1.QueryServer = &AppQueryService{} diff --git a/runtime/internal/services/autocli.go b/runtime/internal/services/autocli.go new file mode 100644 index 000000000000..65b2ee550e1e --- /dev/null +++ b/runtime/internal/services/autocli.go @@ -0,0 +1,37 @@ +package services + +import ( + "context" + + autocliv1 "cosmossdk.io/api/cosmos/autocli/v1" + "cosmossdk.io/core/appmodule" +) + +// AutoCLIQueryService implements the cosmos.autocli.v1.Query service. +type AutoCLIQueryService struct { + autocliv1.UnimplementedQueryServer + + moduleOptions map[string]*autocliv1.ModuleOptions +} + +func NewAutoCLIQueryService(appModules map[string]appmodule.AppModule) *AutoCLIQueryService { + moduleOptions := map[string]*autocliv1.ModuleOptions{} + for modName, mod := range appModules { + if autoCliMod, ok := mod.(interface { + AutoCLIOptions() *autocliv1.ModuleOptions + }); ok { + moduleOptions[modName] = autoCliMod.AutoCLIOptions() + } + } + return &AutoCLIQueryService{ + moduleOptions: moduleOptions, + } +} + +func (a AutoCLIQueryService) AppOptions(context.Context, *autocliv1.AppOptionsRequest) (*autocliv1.AppOptionsResponse, error) { + return &autocliv1.AppOptionsResponse{ + ModuleOptions: a.moduleOptions, + }, nil +} + +var _ autocliv1.QueryServer = &AutoCLIQueryService{} diff --git a/runtime/internal/services/reflection.go b/runtime/internal/services/reflection.go new file mode 100644 index 000000000000..b165ea633ed4 --- /dev/null +++ b/runtime/internal/services/reflection.go @@ -0,0 +1,73 @@ +package services + +import ( + "bytes" + "compress/gzip" + "context" + "io" + + reflectionv1 "cosmossdk.io/api/cosmos/reflection/v1" + "github.com/cosmos/gogoproto/proto" + "golang.org/x/exp/slices" + protov2 "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/reflect/protodesc" + "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/reflect/protoregistry" + "google.golang.org/protobuf/types/descriptorpb" +) + +// ReflectionService implements the cosmos.reflection.v1 service. +type ReflectionService struct { + reflectionv1.UnimplementedReflectionServiceServer + files *descriptorpb.FileDescriptorSet +} + +func NewReflectionService() (*ReflectionService, error) { + fds := &descriptorpb.FileDescriptorSet{} + + // load gogo proto file descriptors + allFds := proto.AllFileDescriptors() + haveFileDescriptor := map[string]bool{} + for _, compressedBz := range allFds { + rdr, err := gzip.NewReader(bytes.NewReader(compressedBz)) + if err != nil { + return nil, err + } + + bz, err := io.ReadAll(rdr) + if err != nil { + return nil, err + } + + fd := &descriptorpb.FileDescriptorProto{} + err = protov2.Unmarshal(bz, fd) + if err != nil { + return nil, err + } + + fds.File = append(fds.File, fd) + haveFileDescriptor[*fd.Name] = true + } + + // load any protoregistry file descriptors not in gogo + protoregistry.GlobalFiles.RangeFiles(func(fileDescriptor protoreflect.FileDescriptor) bool { + if !haveFileDescriptor[fileDescriptor.Path()] { + fds.File = append(fds.File, protodesc.ToFileDescriptorProto(fileDescriptor)) + } + return true + }) + + slices.SortFunc(fds.File, func(x, y *descriptorpb.FileDescriptorProto) bool { + return *x.Name < *y.Name + }) + + return &ReflectionService{files: fds}, nil +} + +func (r ReflectionService) FileDescriptors(_ context.Context, _ *reflectionv1.FileDescriptorsRequest) (*reflectionv1.FileDescriptorsResponse, error) { + return &reflectionv1.FileDescriptorsResponse{ + Files: r.files.File, + }, nil +} + +var _ reflectionv1.ReflectionServiceServer = &ReflectionService{} diff --git a/runtime/module.go b/runtime/module.go index b1bcf77256d6..0f858b0bb50c 100644 --- a/runtime/module.go +++ b/runtime/module.go @@ -6,6 +6,7 @@ import ( abci "github.com/tendermint/tendermint/abci/types" runtimev1alpha1 "cosmossdk.io/api/cosmos/app/runtime/v1alpha1" + appv1alpha1 "cosmossdk.io/api/cosmos/app/v1alpha1" "cosmossdk.io/core/appmodule" "cosmossdk.io/depinject" @@ -77,10 +78,12 @@ func ProvideCodecs(moduleBasics map[string]AppModuleBasicWrapper) ( type appInputs struct { depinject.In + AppConfig *appv1alpha1.Config Config *runtimev1alpha1.Module AppBuilder *AppBuilder Modules map[string]AppModuleWrapper BaseAppOptions []BaseAppOption + AppModules map[string]appmodule.AppModule } func SetupAppBuilder(inputs appInputs) { @@ -92,6 +95,8 @@ func SetupAppBuilder(inputs appInputs) { app.baseAppOptions = inputs.BaseAppOptions app.config = inputs.Config app.ModuleManager = mm + app.appConfig = inputs.AppConfig + app.appModules = inputs.AppModules } func registerStoreKey(wrapper *AppBuilder, key storetypes.StoreKey) { diff --git a/runtime/services.go b/runtime/services.go new file mode 100644 index 000000000000..491b292637a8 --- /dev/null +++ b/runtime/services.go @@ -0,0 +1,22 @@ +package runtime + +import ( + appv1alpha1 "cosmossdk.io/api/cosmos/app/v1alpha1" + autocliv1 "cosmossdk.io/api/cosmos/autocli/v1" + reflectionv1 "cosmossdk.io/api/cosmos/reflection/v1" + + "github.com/cosmos/cosmos-sdk/runtime/internal/services" +) + +func (a *App) registerRuntimeServices() error { + appv1alpha1.RegisterQueryServer(a.GRPCQueryRouter(), services.NewAppQueryService(a.appConfig)) + autocliv1.RegisterQueryServer(a.GRPCQueryRouter(), services.NewAutoCLIQueryService(a.appModules)) + + reflectionSvc, err := services.NewReflectionService() + if err != nil { + return err + } + reflectionv1.RegisterReflectionServiceServer(a.GRPCQueryRouter(), reflectionSvc) + + return nil +} diff --git a/simapp/simd/cmd/root.go b/simapp/simd/cmd/root.go index c4e96d0d6639..9c4289bafa5d 100644 --- a/simapp/simd/cmd/root.go +++ b/simapp/simd/cmd/root.go @@ -15,6 +15,7 @@ import ( "cosmossdk.io/simapp" "cosmossdk.io/simapp/params" + "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/config" diff --git a/tests/go.mod b/tests/go.mod index 4ff94257ba8e..e78c4ae9bb54 100644 --- a/tests/go.mod +++ b/tests/go.mod @@ -15,6 +15,8 @@ require ( github.com/stretchr/testify v1.8.1 github.com/tendermint/tendermint v0.37.0-rc1 github.com/tendermint/tm-db v0.6.7 + google.golang.org/protobuf v1.28.1 + gotest.tools/v3 v3.4.0 pgregory.net/rapid v0.5.3 ) @@ -74,6 +76,7 @@ require ( github.com/golang/protobuf v1.5.2 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/btree v1.1.2 // indirect + github.com/google/go-cmp v0.5.9 // indirect github.com/google/orderedcode v0.0.1 // indirect github.com/googleapis/gax-go/v2 v2.4.0 // indirect github.com/gorilla/handlers v1.5.1 // indirect @@ -149,7 +152,6 @@ require ( google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a // indirect google.golang.org/grpc v1.50.1 // indirect - google.golang.org/protobuf v1.28.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/tests/go.sum b/tests/go.sum index d26a1f8dc7bf..012c62156945 100644 --- a/tests/go.sum +++ b/tests/go.sum @@ -381,6 +381,7 @@ github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= @@ -1391,6 +1392,7 @@ gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools/v3 v3.4.0 h1:ZazjZUfuVeZGLAmlKKuyv3IKP5orXcwtOwDQH6YVr6o= +gotest.tools/v3 v3.4.0/go.mod h1:CtbdzLSsqVhDgMtKsx03ird5YTGB3ar27v0u/yKBW5g= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/tests/integration/runtime/query_test.go b/tests/integration/runtime/query_test.go new file mode 100644 index 000000000000..67090215d56c --- /dev/null +++ b/tests/integration/runtime/query_test.go @@ -0,0 +1,134 @@ +package runtime + +import ( + "testing" + + reflectionv1 "cosmossdk.io/api/cosmos/reflection/v1" + "github.com/cosmos/gogoproto/proto" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/reflect/protoregistry" + "google.golang.org/protobuf/types/descriptorpb" + "gotest.tools/v3/assert" + + appv1alpha1 "cosmossdk.io/api/cosmos/app/v1alpha1" + autocliv1 "cosmossdk.io/api/cosmos/autocli/v1" + + "github.com/cosmos/cosmos-sdk/baseapp" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + "github.com/cosmos/cosmos-sdk/testutil/configurator" + simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" + sdk "github.com/cosmos/cosmos-sdk/types" + + _ "github.com/cosmos/cosmos-sdk/x/auth" + _ "github.com/cosmos/cosmos-sdk/x/auth/tx/module" + _ "github.com/cosmos/cosmos-sdk/x/bank" + _ "github.com/cosmos/cosmos-sdk/x/consensus" + _ "github.com/cosmos/cosmos-sdk/x/params" + _ "github.com/cosmos/cosmos-sdk/x/staking" +) + +type fixture struct { + ctx sdk.Context + appQueryClient appv1alpha1.QueryClient + autocliInfoClient autocliv1.QueryClient + reflectionClient reflectionv1.ReflectionServiceClient +} + +func initFixture(t assert.TestingT) *fixture { + f := &fixture{} + + var interfaceRegistry codectypes.InterfaceRegistry + + app, err := simtestutil.Setup( + configurator.NewAppConfig( + configurator.AuthModule(), + configurator.TxModule(), + configurator.ParamsModule(), + configurator.ConsensusModule(), + configurator.BankModule(), + configurator.StakingModule(), + ), + &interfaceRegistry, + ) + assert.NilError(t, err) + + f.ctx = app.BaseApp.NewContext(false, tmproto.Header{}) + queryHelper := &baseapp.QueryServiceTestHelper{ + GRPCQueryRouter: app.BaseApp.GRPCQueryRouter(), + Ctx: f.ctx, + } + f.appQueryClient = appv1alpha1.NewQueryClient(queryHelper) + f.autocliInfoClient = autocliv1.NewQueryClient(queryHelper) + f.reflectionClient = reflectionv1.NewReflectionServiceClient(queryHelper) + + return f +} + +func TestQueryAppConfig(t *testing.T) { + t.Parallel() + f := initFixture(t) + + res, err := f.appQueryClient.Config(f.ctx, &appv1alpha1.QueryConfigRequest{}) + assert.NilError(t, err) + // app config is not nil + assert.Assert(t, res != nil && res.Config != nil) + + moduleConfigs := map[string]*appv1alpha1.ModuleConfig{} + for _, module := range res.Config.Modules { + moduleConfigs[module.Name] = module + } + + // has all expected modules + for _, modName := range []string{"auth", "bank", "tx", "consensus", "runtime", "params", "staking"} { + modConfig := moduleConfigs[modName] + if modConfig == nil { + t.Fatalf("missing %s", modName) + } + assert.Assert(t, modConfig.Config != nil) + } +} + +func TestReflectionService(t *testing.T) { + t.Parallel() + f := initFixture(t) + + res, err := f.reflectionClient.FileDescriptors(f.ctx, &reflectionv1.FileDescriptorsRequest{}) + assert.NilError(t, err) + assert.Assert(t, res != nil && res.Files != nil) + + fdMap := map[string]*descriptorpb.FileDescriptorProto{} + for _, descriptorProto := range res.Files { + fdMap[*descriptorProto.Name] = descriptorProto + } + + // check all file descriptors from gogo are present + for path := range proto.AllFileDescriptors() { + if fdMap[path] == nil { + t.Fatalf("missing %s", path) + } + } + + // check all file descriptors from protoregistry are present + protoregistry.GlobalFiles.RangeFiles(func(fileDescriptor protoreflect.FileDescriptor) bool { + path := fileDescriptor.Path() + if fdMap[path] == nil { + t.Fatalf("missing %s", path) + } + return true + }) +} + +func TestQueryAutoCLIAppOptions(t *testing.T) { + t.Parallel() + f := initFixture(t) + + res, err := f.autocliInfoClient.AppOptions(f.ctx, &autocliv1.AppOptionsRequest{}) + assert.NilError(t, err) + assert.Assert(t, res != nil && res.ModuleOptions != nil) + + // make sure we at least have x/auth autocli options + authOpts := res.ModuleOptions["auth"] + assert.Assert(t, authOpts != nil) + assert.Assert(t, authOpts.Query != nil && authOpts.Query.Service != "") +} diff --git a/x/auth/module.go b/x/auth/module.go index 7f5c83461974..52064974f9e3 100644 --- a/x/auth/module.go +++ b/x/auth/module.go @@ -5,13 +5,17 @@ import ( "encoding/json" "fmt" - modulev1 "cosmossdk.io/api/cosmos/auth/module/v1" - "cosmossdk.io/core/appmodule" - "cosmossdk.io/depinject" gwruntime "github.com/grpc-ecosystem/grpc-gateway/runtime" "github.com/spf13/cobra" abci "github.com/tendermint/tendermint/abci/types" + "cosmossdk.io/depinject" + + autocliv1 "cosmossdk.io/api/cosmos/autocli/v1" + "cosmossdk.io/core/appmodule" + + modulev1 "cosmossdk.io/api/cosmos/auth/module/v1" + "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" codectypes "github.com/cosmos/cosmos-sdk/codec/types" @@ -99,6 +103,19 @@ type AppModule struct { legacySubspace exported.Subspace } +var _ appmodule.AppModule = AppModule{} + +// IsOnePerModuleType implements the depinject.OnePerModuleType interface. +func (am AppModule) IsOnePerModuleType() {} + +// IsAppModule implements the appmodule.AppModule interface. +func (am AppModule) IsAppModule() {} + +// AutoCLIOptions implements the autocli.HasAutoCLIConfig interface. +func (am AppModule) AutoCLIOptions() *autocliv1.ModuleOptions { + return types.AutoCLIOptions +} + // NewAppModule creates a new AppModule object func NewAppModule(cdc codec.Codec, accountKeeper keeper.AccountKeeper, randGenAccountsFn types.RandomGenesisAccountsFn, ss exported.Subspace) AppModule { return AppModule{ @@ -184,7 +201,10 @@ func (AppModule) WeightedOperations(_ module.SimulationState) []simtypes.Weighte func init() { appmodule.Register(&modulev1.Module{}, - appmodule.Provide(ProvideModuleBasic, ProvideModule), + appmodule.Provide( + ProvideModuleBasic, + ProvideModule, + ), ) } @@ -211,6 +231,7 @@ type AuthOutputs struct { AccountKeeper keeper.AccountKeeper Module runtime.AppModuleWrapper + NewAppModule appmodule.AppModule } func ProvideModule(in AuthInputs) AuthOutputs { @@ -236,5 +257,5 @@ func ProvideModule(in AuthInputs) AuthOutputs { k := keeper.NewAccountKeeper(in.Cdc, in.Key, in.AccountI, maccPerms, in.Config.Bech32Prefix, authority.String()) m := NewAppModule(in.Cdc, k, in.RandomGenesisAccountsFn, in.LegacySubspace) - return AuthOutputs{AccountKeeper: k, Module: runtime.WrapAppModule(m)} + return AuthOutputs{AccountKeeper: k, Module: runtime.WrapAppModule(m), NewAppModule: m} } diff --git a/x/auth/types/account_test.go b/x/auth/types/account_test.go index 571dc2ec90d2..f666cef899fd 100644 --- a/x/auth/types/account_test.go +++ b/x/auth/types/account_test.go @@ -10,6 +10,7 @@ import ( "sigs.k8s.io/yaml" "cosmossdk.io/depinject" + "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" "github.com/cosmos/cosmos-sdk/testutil/testdata" sdk "github.com/cosmos/cosmos-sdk/types" diff --git a/x/auth/types/autocli.go b/x/auth/types/autocli.go new file mode 100644 index 000000000000..4257ed4c244a --- /dev/null +++ b/x/auth/types/autocli.go @@ -0,0 +1,26 @@ +package types + +import autocliv1 "cosmossdk.io/api/cosmos/autocli/v1" + +var AutoCLIOptions = &autocliv1.ModuleOptions{ + Query: &autocliv1.ServiceCommandDescriptor{ + Service: _Query_serviceDesc.ServiceName, + RpcCommandOptions: []*autocliv1.RpcCommandOptions{ + { + RpcMethod: "Account", + Use: "account [address]", + Short: "query account by address", + PositionalArgs: []*autocliv1.PositionalArgDescriptor{{ProtoField: "address"}}, + }, + { + RpcMethod: "AccountAddressByID", + Use: "address-by-id [id]", + Short: "query account address by account ID", + PositionalArgs: []*autocliv1.PositionalArgDescriptor{{ProtoField: "id"}}, + }, + }, + }, + Tx: &autocliv1.ServiceCommandDescriptor{ + Service: _Msg_serviceDesc.ServiceName, + }, +} diff --git a/x/auth/vesting/module.go b/x/auth/vesting/module.go index 71439a6a0f0d..8168447da9cf 100644 --- a/x/auth/vesting/module.go +++ b/x/auth/vesting/module.go @@ -8,6 +8,7 @@ import ( abci "github.com/tendermint/tendermint/abci/types" "cosmossdk.io/depinject" + "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" codectypes "github.com/cosmos/cosmos-sdk/codec/types" @@ -17,6 +18,7 @@ import ( modulev1 "cosmossdk.io/api/cosmos/vesting/module/v1" "cosmossdk.io/core/appmodule" + "github.com/cosmos/cosmos-sdk/x/auth/keeper" "github.com/cosmos/cosmos-sdk/x/auth/vesting/client/cli" "github.com/cosmos/cosmos-sdk/x/auth/vesting/types" diff --git a/x/capability/module.go b/x/capability/module.go index 510dfa00d6d4..843eb3f6e778 100644 --- a/x/capability/module.go +++ b/x/capability/module.go @@ -14,6 +14,7 @@ import ( modulev1 "cosmossdk.io/api/cosmos/capability/module/v1" "cosmossdk.io/depinject" + "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" cdctypes "github.com/cosmos/cosmos-sdk/codec/types" diff --git a/x/evidence/module.go b/x/evidence/module.go index a777b15e6b86..fdda380bd071 100644 --- a/x/evidence/module.go +++ b/x/evidence/module.go @@ -12,6 +12,7 @@ import ( "cosmossdk.io/core/appmodule" "cosmossdk.io/depinject" + "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" codectypes "github.com/cosmos/cosmos-sdk/codec/types" @@ -22,6 +23,7 @@ import ( simtypes "github.com/cosmos/cosmos-sdk/types/simulation" modulev1 "cosmossdk.io/api/cosmos/evidence/module/v1" + eviclient "github.com/cosmos/cosmos-sdk/x/evidence/client" "github.com/cosmos/cosmos-sdk/x/evidence/client/cli" "github.com/cosmos/cosmos-sdk/x/evidence/keeper"