diff --git a/core/appconfig/config.go b/core/appconfig/config.go index 27db644ecff4..75c9c2e90571 100644 --- a/core/appconfig/config.go +++ b/core/appconfig/config.go @@ -2,7 +2,6 @@ package appconfig import ( "fmt" - "reflect" "strings" "google.golang.org/protobuf/encoding/protojson" @@ -94,14 +93,7 @@ func Compose(appConfig *appv1alpha1.Config) depinject.Config { return depinject.Error(err) } - opts = append(opts, depinject.Provide(depinject.ProviderDescriptor{ - Inputs: nil, - Outputs: []depinject.ProviderOutput{{Type: init.ConfigGoType}}, - Fn: func(values []reflect.Value) ([]reflect.Value, error) { - return []reflect.Value{reflect.ValueOf(config)}, nil - }, - Location: depinject.LocationFromCaller(0), - })) + opts = append(opts, depinject.Supply(config)) for _, provider := range init.Providers { opts = append(opts, depinject.ProvideInModule(module.Name, provider)) diff --git a/core/appconfig/config_test.go b/core/appconfig/config_test.go index c5d04ba48465..e67408f6908a 100644 --- a/core/appconfig/config_test.go +++ b/core/appconfig/config_test.go @@ -2,17 +2,21 @@ package appconfig_test import ( "bytes" + "fmt" + "io" "reflect" + "sort" "testing" "gotest.tools/v3/assert" + "cosmossdk.io/depinject" + "cosmossdk.io/core/appconfig" "cosmossdk.io/core/appmodule" "cosmossdk.io/core/internal" "cosmossdk.io/core/internal/testpb" _ "cosmossdk.io/core/internal/testpb" - "cosmossdk.io/depinject" ) func expectContainerErrorContains(t *testing.T, option depinject.Config, contains string) { @@ -56,7 +60,7 @@ modules: expectContainerErrorContains(t, opt, "registered modules are") expectContainerErrorContains(t, opt, "testpb.TestModuleA") - var app testpb.App + var app App opt = appconfig.LoadYAML([]byte(` modules: - name: runtime @@ -119,3 +123,103 @@ modules: `)) expectContainerErrorContains(t, opt, "module should have ModuleDescriptor.go_import specified") } + +// +// Test Module Initialization Logic +// + +func init() { + appmodule.Register(&testpb.TestRuntimeModule{}, + appmodule.Provide(ProvideRuntimeState, ProvideStoreKey, ProvideApp), + ) + + appmodule.Register(&testpb.TestModuleA{}, + appmodule.Provide(ProvideModuleA), + ) + + appmodule.Register(&testpb.TestModuleB{}, + appmodule.Provide(ProvideModuleB), + ) +} + +func ProvideRuntimeState() *RuntimeState { + return &RuntimeState{} +} + +func ProvideStoreKey(key depinject.ModuleKey, state *RuntimeState) StoreKey { + sk := StoreKey{name: key.Name()} + state.storeKeys = append(state.storeKeys, sk) + return sk +} + +func ProvideApp(state *RuntimeState, handlers map[string]Handler) App { + return func(w io.Writer) { + sort.Slice(state.storeKeys, func(i, j int) bool { + return state.storeKeys[i].name < state.storeKeys[j].name + }) + + for _, key := range state.storeKeys { + _, _ = fmt.Fprintf(w, "got store key %s\n", key.name) + } + + var modNames []string + for modName := range handlers { + modNames = append(modNames, modName) + } + + sort.Strings(modNames) + for _, name := range modNames { + _, _ = fmt.Fprintf(w, "running module handler %s\n", name) + _, _ = fmt.Fprintf(w, "result: %s\n", handlers[name].DoSomething()) + } + } +} + +type App func(writer io.Writer) + +type RuntimeState struct { + storeKeys []StoreKey +} + +type StoreKey struct{ name string } + +type Handler struct { + DoSomething func() string +} + +func (h Handler) IsOnePerModuleType() {} + +func ProvideModuleA(key StoreKey) (KeeperA, Handler) { + return keeperA{key: key}, Handler{DoSomething: func() string { + return "hello" + }} +} + +type keeperA struct { + key StoreKey +} + +type KeeperA interface { + Foo() +} + +func (k keeperA) Foo() {} + +func ProvideModuleB(key StoreKey, a KeeperA) (KeeperB, Handler) { + return keeperB{key: key, a: a}, Handler{ + DoSomething: func() string { + return "goodbye" + }, + } +} + +type keeperB struct { + key StoreKey + a KeeperA +} + +type KeeperB interface { + isKeeperB() +} + +func (k keeperB) isKeeperB() {} diff --git a/core/appmodule/option.go b/core/appmodule/option.go index ee1ee6492f72..4c041c0cb707 100644 --- a/core/appmodule/option.go +++ b/core/appmodule/option.go @@ -2,7 +2,6 @@ package appmodule import ( "cosmossdk.io/core/internal" - "cosmossdk.io/depinject" ) // Option is a functional option for implementing modules. @@ -22,12 +21,7 @@ func (f funcOption) apply(initializer *internal.ModuleInitializer) error { func Provide(providers ...interface{}) Option { return funcOption(func(initializer *internal.ModuleInitializer) error { for _, provider := range providers { - desc, err := depinject.ExtractProviderDescriptor(provider) - if err != nil { - return err - } - - initializer.Providers = append(initializer.Providers, desc) + initializer.Providers = append(initializer.Providers, provider) } return nil }) @@ -40,12 +34,7 @@ func Provide(providers ...interface{}) Option { func Invoke(invokers ...interface{}) Option { return funcOption(func(initializer *internal.ModuleInitializer) error { for _, invoker := range invokers { - desc, err := depinject.ExtractInvokerDescriptor(invoker) - if err != nil { - return err - } - - initializer.Invokers = append(initializer.Invokers, desc) + initializer.Invokers = append(initializer.Invokers, invoker) } return nil }) diff --git a/core/go.mod b/core/go.mod index ce5cb8590d13..321ff3fbb6a3 100644 --- a/core/go.mod +++ b/core/go.mod @@ -4,7 +4,7 @@ go 1.18 require ( cosmossdk.io/api v0.1.0-alpha9 - cosmossdk.io/depinject v1.0.0-alpha.2 + cosmossdk.io/depinject v1.0.0-alpha.3 github.com/cosmos/cosmos-proto v1.0.0-alpha7 google.golang.org/protobuf v1.28.1 gotest.tools/v3 v3.3.0 @@ -16,7 +16,7 @@ require ( github.com/google/go-cmp v0.5.8 // indirect github.com/kr/text v0.2.0 // indirect github.com/pkg/errors v0.9.1 // indirect - golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect + golang.org/x/exp v0.0.0-20220827204233-334a2380cb91 // indirect golang.org/x/net v0.0.0-20220726230323-06994584191e // indirect golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab // indirect golang.org/x/text v0.3.7 // indirect diff --git a/core/go.sum b/core/go.sum index 9363f44e91af..00781cfbe2f1 100644 --- a/core/go.sum +++ b/core/go.sum @@ -1,7 +1,7 @@ cosmossdk.io/api v0.1.0-alpha9 h1:8QQT+BhaMpcCgR4Wm8JVuhhtj4a7uZjsxvvWvmsQFB0= cosmossdk.io/api v0.1.0-alpha9/go.mod h1:PyJpp0BY4tHLI0kzkiUzpZxgOE+pJbhDPleYrA5yVio= -cosmossdk.io/depinject v1.0.0-alpha.2 h1:pVcPnqc8bY2GCHVMj77rk6Ew7uz0K3QhrUHdqoKvO5g= -cosmossdk.io/depinject v1.0.0-alpha.2/go.mod h1:Wmu0TV/H4s4s8zaJ9YnaioLyCbqlCvMQ4xTtzJzGzvA= +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-alpha7 h1:yqYUOHF2jopwZh4dVQp3xgqwftE5/2hkrwIV6vkUbO0= @@ -37,8 +37,8 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec 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-20220722155223-a9213eeb770e h1:+WEEuIdZHnUeJJmEUjyYC2gfUMj69yZXw17EnHg/otA= -golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA= +golang.org/x/exp v0.0.0-20220827204233-334a2380cb91 h1:tnebWN09GYg9OLPss1KXj8txwZc6X6uMr6VFdcGNbHw= +golang.org/x/exp v0.0.0-20220827204233-334a2380cb91/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= @@ -82,6 +82,6 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gotest.tools/v3 v3.3.0 h1:MfDY1b1/0xN1CyMlQDac0ziEy9zJQd9CXBRRDHw2jJo= gotest.tools/v3 v3.3.0/go.mod h1:Mcr9QNxkg0uMvy/YElmo4SpXgJKWgQvYrT7Kw5RzJ1A= pgregory.net/rapid v0.4.7/go.mod h1:UYpPVyjFHzYBGHIxLFoupi8vwk6rXNzRY9OMvVxFIOU= -pgregory.net/rapid v0.4.8 h1:d+5SGZWUbJPbl3ss6tmPFqnNeQR6VDOFly+eTjwPiEw= +pgregory.net/rapid v0.5.2 h1:zC+jmuzcz5yJvG/igG06aLx8kcGmZY435NcuyhblKjY= sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= diff --git a/core/internal/registry.go b/core/internal/registry.go index beb8a5446332..ce8dbb203f17 100644 --- a/core/internal/registry.go +++ b/core/internal/registry.go @@ -8,8 +8,6 @@ import ( "google.golang.org/protobuf/reflect/protoreflect" appv1alpha1 "cosmossdk.io/api/cosmos/app/v1alpha1" - - "cosmossdk.io/depinject" ) // ModuleRegistry is the registry of module initializers indexed by their golang @@ -21,8 +19,8 @@ type ModuleInitializer struct { ConfigGoType reflect.Type ConfigProtoMessage proto.Message Error error - Providers []depinject.ProviderDescriptor - Invokers []depinject.ProviderDescriptor + Providers []interface{} + Invokers []interface{} } // ModulesByProtoMessageName should be used to retrieve modules by their protobuf name. diff --git a/core/internal/testpb/modules.go b/core/internal/testpb/modules.go deleted file mode 100644 index c554ad73e236..000000000000 --- a/core/internal/testpb/modules.go +++ /dev/null @@ -1,106 +0,0 @@ -package testpb - -import ( - "fmt" - "io" - "sort" - - "cosmossdk.io/core/appmodule" - "cosmossdk.io/depinject" -) - -func init() { - appmodule.Register(&TestRuntimeModule{}, - appmodule.Provide(provideRuntimeState, provideStoreKey, provideApp), - ) - - appmodule.Register(&TestModuleA{}, - appmodule.Provide(provideModuleA), - ) - - appmodule.Register(&TestModuleB{}, - appmodule.Provide(provideModuleB), - ) -} - -func provideRuntimeState() *runtimeState { - return &runtimeState{} -} - -func provideStoreKey(key depinject.ModuleKey, state *runtimeState) StoreKey { - sk := StoreKey{name: key.Name()} - state.storeKeys = append(state.storeKeys, sk) - return sk -} - -func provideApp(state *runtimeState, handlers map[string]Handler) App { - return func(w io.Writer) { - sort.Slice(state.storeKeys, func(i, j int) bool { - return state.storeKeys[i].name < state.storeKeys[j].name - }) - - for _, key := range state.storeKeys { - _, _ = fmt.Fprintf(w, "got store key %s\n", key.name) - } - - var modNames []string - for modName := range handlers { - modNames = append(modNames, modName) - } - - sort.Strings(modNames) - for _, name := range modNames { - _, _ = fmt.Fprintf(w, "running module handler %s\n", name) - _, _ = fmt.Fprintf(w, "result: %s\n", handlers[name].DoSomething()) - } - } -} - -type App func(writer io.Writer) - -type runtimeState struct { - storeKeys []StoreKey -} - -type StoreKey struct{ name string } - -type Handler struct { - DoSomething func() string -} - -func (h Handler) IsOnePerModuleType() {} - -func provideModuleA(key StoreKey) (KeeperA, Handler) { - return keeperA{key: key}, Handler{DoSomething: func() string { - return "hello" - }} -} - -type keeperA struct { - key StoreKey -} - -type KeeperA interface { - Foo() -} - -func (k keeperA) Foo() {} - -func provideModuleB(key StoreKey, a KeeperA) (KeeperB, Handler) { - return keeperB{key: key, a: a}, Handler{ - DoSomething: func() string { - return "goodbye" - }, - } -} - -type keeperB struct { - key StoreKey - a KeeperA -} - -type KeeperB interface { - isKeeperB() -} - -func (k keeperB) isKeeperB() {}