Replies: 9 comments 29 replies
-
Really cool, we might even be able to add new modules via rolling upgrades using this feature. |
Beta Was this translation helpful? Give feedback.
-
I've been thinking about this dependency approach in terms of usage within the group module:
|
Beta Was this translation helpful? Give feedback.
-
Internally, in past months we were discussing this issue, so it's worth to link the Regen issue where were experimenting with the refactore: regen-network/regen-ledger#301 Few highlights:
|
Beta Was this translation helpful? Give feedback.
-
This looks like a great initiative 👍 Representing https://github.com/tendermint/starport as one of the users of Cosmos SDK, there are two important requirements from our side.
Also, since a chain needs to keep a list of imported modules, may I suggest using
modules:
- type: "/cosmos.auth.module.v1.Module"
- type: "/cosmos.bank.module.v2.Module"
params:
key: value |
Beta Was this translation helpful? Give feedback.
-
So I am generally starting to think of a new strategy here that allows us to deploy improvements to the current app.go UX without doing a lot of refactoring of existing modules. I still think many of the existing modules need to evolve and be refactored/redesigned but I don't think we can wait to have every module implemented ADR 033 before we can improve app.go. Basically, by creating the right kid of dependency injection (DI) container, I think we can enable a declarative config like I've described above with the current module set mostly unmodified. I have a proof of concept PR I've been working on (#9398), with a partially working DI container that I think will work fine for our current keepers/AppModule's and even allow for some (optional) declarative Ocaps-like security. Some example config JSON is here: https://github.com/cosmos/cosmos-sdk/blob/b0a93479520730d576e94e11716d4f9b603c6a31/simapp2/app_config.json. I might do a bit more work on this approach and show a minimal example where we could wire up the existing x/auth and x/bank like this (WIP here: #9442). If we go with this approach, I'm also thinking that maybe some of the bigger refactors we're thinking of (ex. #9336 and #9066) might be best framed as proper |
Beta Was this translation helpful? Give feedback.
-
Store as a keeper dependencyWe are considering a different way to provide a store. Instead of accessing a store through a context and module key:
|
Beta Was this translation helpful? Give feedback.
-
I just want to give an update on my latest thinking to see if anyone has any feedback. My latest proof of concept is in #9529. Approach
This uses Uber's dig dependency injection container under the hood. BenefitsThis will allow us to create a very simple This means that it's likely we can deliver this relatively quickly. It's not even API breaking and could theoretically be backported to 0.42 or 0.43. Possible DrawbacksThe main possible drawbacks to this approach are:
PlanIf we stakeholders feel that this is a valuable improvement and that the developer UX for this is reasonable, I would like to move this forward relatively quickly (i.e. over the summer) and starting refining all the details. Let me know what you think. |
Beta Was this translation helpful? Give feedback.
-
From the developer experience perspective there are two things we are most concerned about:
In the latest presented design the way modules will be handled is by:
So far, so good. I would still prefer to have Starport's YAML config and modules YAML file be in the same file, but that's not a dealbreaker. Programmatically adding features is another story. Instead of making proposals on the architecture, I'll go from end-users' perspective. Here is an example of a scaffolded vanilla chain with Problem areas (placeholders):
A framework user should be able to add CRUD functionality programmatically with a tool like Starport without having to rely on placeholders. |
Beta Was this translation helpful? Give feedback.
-
I'm listing here my thoughts after yesterday's call. Pros:
Cons:
Question:
Suggestions: Provide a minimum viable module definition similar to poc, example: type Module struct {
Name string // name of module
MsgHandler interface{} // grpc msg server
QueryHandler interface{} // grpc query server
GenesisHandler GenesisHandler // interface that handles genesis with methods Default/Validate/Import/Export
TxCmd cobra.Command
QueryCmd cobra.Command
Provides interface{} // provides is what module exposes with dig outputs
Needs interface{} // Needs is what this module needs with dig inputs
} A module is represented by this structure, and this structure should be what a module is. Suggestion n2: Suffer some more with messy app.go and put more efforts into ADR-033 and ADR-033 migration. This is what I feel is future proof. |
Beta Was this translation helpful? Give feedback.
-
ADR 033 describes a mechanism for inter-module communication based off of protobuf
service
code generation. One aspect of ADR 033 that has been discussed but isn’t fully specified is how this approach affectsapp.go
module/keeper wiring which is actually one of the biggest goals and potential benefits of this approach.The high-level goals I have in mind for ADR 033 and
app.go
are:app.go
wiring as minimal as possible so that a) it is easier to spin-up apps in module tests and b) properly wiring up an app is simpler and less error proneGoals
I want to briefly describe a few goals I have for app wiring.
Goal 1: Make app wiring much simpler
The key benefits I see for this are:
app.go
would be much shorter simpler and less error proneEasier integration test fixtures are a particularly big pain point for me having attempted to develop modules outside of an app a few times in the past and having needed to basically completely replicate “simapp” to do any real end to end testing.
Goal 2: Make app wiring completely declarative
The idea here is that basically the entire module wiring configuration could basically be serialized to and from JSON/protobuf.
The hasn’t been talked about much but it could be potentially quite valuable for zones because it makes basically the entire app configuration mutable by governance. This could allow zones to spin up binaries with experimental modules that aren’t enabled initially but that can be switched on with a param change vote. Also, this basically reduces the surface area for parameters not configurable by governance to zero.
One particular case I’m holding in mind for the send deny-list issue that needed to be patched in
app.go
recently.Example declarative config:
Module Design
In order to accomplish this I want to propose the following rough
Module
interface redesign.We start with a basic
Module
interface that kind of replacesAppModuleBasic
which has a functionNewAppModule
which returns an instance ofAppModule
:Using ADR 033, modules can talk to other modules using the
ModuleKey
to constructMsgClient
andQueryClient
instances.Dependency Injection Option
To make the construction of
MsgClient
andQueryClient
instances more ergonomic and fool-proof, we could consider an optional dependency injection approach that would look something like this:This would eliminate the need to have a manual “require dependencies” step as described in ADR 033 which developers may forget and force the dependency resolution problem into the framework.
There are still many other issues that would need to be worked out to make this happen such as how do we wire
AnteHandler
s, plugins, and all sorts of other config parameters, but I want to get the discussion started.I want to also be clear that in terms of priorities, I strongly believe we should work towards Goal 1 incrementally and first, before trying to make the config fully declarative which may even be deemed a long-term nice to have.
Beta Was this translation helpful? Give feedback.
All reactions