docs: runtime docs + fix runtime missing field (#22816) (#24429)

Co-authored-by: Alex | Interchain Labs <alex@interchainlabs.io>
Co-authored-by: Tyler <48813565+technicallyty@users.noreply.github.com>
This commit is contained in:
julienrbrt 2025-04-09 20:11:21 +02:00 committed by GitHub
parent 65acc32084
commit 6a1ec1bfc0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 211 additions and 33 deletions

View File

@ -33,7 +33,7 @@ https://github.com/cosmos/cosmos-sdk/blob/v0.53.0-rc.2/baseapp/abci_utils.go
```
This default implementation can be overridden by the application developer in
favor of a custom implementation in [`app_di.go`](../building-apps/01-app-go-v2.md):
favor of a custom implementation in [`app_di.go`](../building-apps/01-app-go-di.md):
```go
prepareOpt := func(app *baseapp.BaseApp) {

View File

@ -18,7 +18,7 @@ https://github.com/cosmos/cosmos-sdk/blob/v0.53.0-rc.2/baseapp/abci_utils.go#L21
```
Like `PrepareProposal`, this implementation is the default and can be modified by
the application developer in [`app_di.go`](../building-apps/01-app-go-v2.md). If you decide to implement
the application developer in [`app_di.go`](../building-apps/01-app-go-di.md). If you decide to implement
your own `ProcessProposal` handler, you must ensure that the transactions
provided in the proposal DO NOT exceed the maximum block gas and `maxtxbytes` (if set).

View File

@ -0,0 +1,152 @@
---
sidebar_position: 1
---
# What is `runtime`?
The `runtime` package in the Cosmos SDK provides a flexible framework for configuring and managing blockchain applications. It serves as the foundation for creating modular blockchain applications using a declarative configuration approach.
## Overview
The runtime package acts as a wrapper around the `BaseApp` and `ModuleManager`, offering a hybrid approach where applications can be configured both declaratively through configuration files and programmatically through traditional methods.
It is a layer of abstraction between `baseapp` and the application modules that simplifies the process of building a Cosmos SDK application.
## Core Components
### App Structure
The runtime App struct contains several key components:
```go
type App struct {
*baseapp.BaseApp
ModuleManager *module.Manager
configurator module.Configurator
config *runtimev1alpha1.Module
storeKeys []storetypes.StoreKey
// ... other fields
}
```
Cosmos SDK applications should embed the `*runtime.App` struct to leverage the runtime module.
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.53.0-rc.2/simapp/app_di.go#L60-L61
```
### Configuration
The runtime module is configured using App Wiring. The main configuration object is the [`Module` message](https://github.com/cosmos/cosmos-sdk/blob/v0.53.0-rc.2/proto/cosmos/app/runtime/v1alpha1/module.proto), which supports the following key settings:
* `app_name`: The name of the application
* `begin_blockers`: List of module names to call during BeginBlock
* `end_blockers`: List of module names to call during EndBlock
* `init_genesis`: Order of module initialization during genesis
* `export_genesis`: Order for exporting module genesis data
* `pre_blockers`: Modules to execute before block processing
Learn more about wiring `runtime` in the [next section](./01-app-go-di.md).
#### Store Configuration
By default, the runtime module uses the module name as the store key.
However it provides a flexible store key configuration through:
* `override_store_keys`: Allows customizing module store keys
* `skip_store_keys`: Specifies store keys to skip during keeper construction
Example configuration:
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.53.0-rc.2/simapp/app_config.go#L133-L138
```
## Key Features
### 1. BaseApp and other Core SDK components integration
The runtime module integrates with the `BaseApp` and other core SDK components to provide a seamless experience for developers.
The developer only needs to embed the `runtime.App` struct in their application to leverage the runtime module.
The configuration of the module manager and other core components is handled internally via the [`AppBuilder`](#4-application-building).
### 2. Module Registration
Runtime has built-in support for [`depinject`-enabled modules](../building-modules/15-depinject.md).
Such modules can be registered through the configuration file (often named `app_config.go`), with no additional code required.
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.53.0-rc.2/simapp/app_config.go#L210-L216
```
Additionally, the runtime package facilitates manual module registration through the `RegisterModules` method. This is the primary integration point for modules not registered via configuration.
:::warning
Even when using manual registration, the module should still be configured in the `Module` message in AppConfig.
:::
```go
func (a *App) RegisterModules(modules ...module.AppModule) error
```
The SDK recommends using the declarative approach with `depinject` for module registration whenever possible.
### 3. Service Registration
Runtime registers all [core services](https://pkg.go.dev/cosmossdk.io/core) required by modules.
These services include `store`, `event manager`, `context`, and `logger`.
Runtime ensures that services are scoped to their respective modules during the wiring process.
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.53.0-rc.2/runtime/module.go#L201-L235
```
Additionally, runtime provides automatic registration of other essential (i.e., gRPC routes) services available to the App:
* AutoCLI Query Service
* Reflection Service
* Custom module services
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.53.0-rc.2/runtime/builder.go#L52-L54
```
### 4. Application Building
The `AppBuilder` type provides a structured way to build applications:
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.53.0-rc.2/runtime/builder.go#L14-L19
```
Key building steps:
1. Configuration loading
2. Module registration
3. Service setup
4. Store mounting
5. Router configuration
An application only needs to call `AppBuilder.Build` to create a fully configured application (`runtime.App`).
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.53.0-rc.2/runtime/builder.go#L26-L57
```
More information on building applications can be found in the [next section](./02-app-building.md).
## Best Practices
1. **Module Order**: Carefully consider the order of modules in begin_blockers, end_blockers, and pre_blockers.
2. **Store Keys**: Use override_store_keys only when necessary to maintain clarity
3. **Genesis Order**: Maintain correct initialization order in init_genesis
4. **Migration Management**: Use order_migrations to control upgrade paths
### Migration Considerations
When upgrading between versions:
1. Review the migration order specified in `order_migrations`
2. Ensure all required modules are included in the configuration
3. Validate store key configurations
4. Test the upgrade path thoroughly

View File

@ -6,16 +6,17 @@ sidebar_position: 1
:::note Synopsis
The Cosmos SDK allows much easier wiring of an `app.go` thanks to App Wiring and [`depinject`](../packages/01-depinject.md).
The Cosmos SDK allows much easier wiring of an `app.go` thanks to [runtime](./00-runtime.md) and app wiring.
Learn more about the rationale of App Wiring in [ADR-057](../architecture/adr-057-app-wiring.md).
:::
:::note Pre-requisite Readings
* [ADR 057: App Wiring](../architecture/adr-057-app-wiring.md)
* [Depinject Documentation](../packages/01-depinject.md)
* [What is `runtime`?](./00-runtime.md)
* [Depinject documentation](../packages/01-depinject.md)
* [Modules depinject-ready](../building-modules/15-depinject.md)
* [ADR 057: App Wiring](../architecture/adr-057-app-wiring.md)
:::
@ -28,30 +29,39 @@ The `app_config.go` file is the single place to configure all modules parameters
1. Create the `AppConfig` variable:
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.53.0-rc.2/simapp/app_config.go#L290
https://github.com/cosmos/cosmos-sdk/blob/v0.53.0-rc.2/simapp/app_config.go#L289-L303
```
Where the `appConfig` combines the [runtime](./00-runtime.md) configuration and the (extra) modules configuration.
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.53.0-rc.2/simapp/app_di.go#L113-L161
```
2. Configure the `runtime` module:
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.53.0-rc.2/simapp/app_config.go#L289-L302
```
3. Configure the modules defined in the `PreBlocker`, `BeginBlocker` and `EndBlocker` and the `tx` module:
In this configuration, the order at which the modules are defined in PreBlockers, BeginBlocks, and EndBlockers is important.
They are named in the order they should be executed by the module manager.
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.53.0-rc.2/simapp/app_config.go#L108-L132
https://github.com/cosmos/cosmos-sdk/blob/v0.53.0-rc.2/simapp/app_config.go#L103-L188
```
3. Wire the other modules:
Next to runtime, the other (depinject-enabled) modules are wired in the `AppConfig`:
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.53.0-rc.2/simapp/app_config.go#L103-L286
```
Note: the `tx` isn't a module, but a configuration. It should be wired in the `AppConfig` as well.
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.53.0-rc.2/simapp/app_config.go#L222-L227
```
### Complete `app_config.go`
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.53.0-rc.2/simapp/app_config.go
```
See the complete `app_config.go` file for `SimApp` [here](https://github.com/cosmos/cosmos-sdk/blob/v0.53.0-rc.2/simapp/app_config.go).
### Alternative formats
@ -93,12 +103,12 @@ modules:
"@type": cosmos.tx.module.v1.Module
```
A more complete example of `app.yaml` can be found [here](https://github.com/cosmos/cosmos-sdk/blob/91b1d83f1339e235a1dfa929ecc00084101a19e3/simapp/app.yaml).
A more complete example of `app.yaml` can be found [here](https://github.com/cosmonity/chain-minimal/blob/mini-v050.3/app/app.yaml).
## `app_di.go`
`app_di.go` is the place where `SimApp` is constructed. `depinject.Inject` facilitates this by automatically wiring the app modules and keepers, with the provided application configuration `AppConfig`. `SimApp` is constructed upon calling the `Build` method on the injected `*runtime.AppBuilder`.
In short, `depinject` and the [`runtime` package](https://pkg.go.dev/github.com/cosmos/cosmos-sdk/runtime) abstract the wiring of the app, and the `AppBuilder` takes care of constructing the application. [`runtime`](https://pkg.go.dev/github.com/cosmos/cosmos-sdk/runtime) handles registering the codecs, KV store, subspaces, and instantiating `baseapp`.
`app_di.go` is the place where `SimApp` is constructed. `depinject.Inject` automatically wires the app modules and keepers when provided with an application configuration (`AppConfig`). `SimApp` is constructed upon calling the injected `*runtime.AppBuilder` with `appBuilder.Build(...)`.
In short `depinject` and the [`runtime` package](./00-runtime.md) abstract the wiring of the app, and the `AppBuilder` is the place where the app is constructed. [`runtime`](./00-runtime.md) takes care of registering the codecs, KV store, subspaces and instantiating `baseapp`.
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.53.0-rc.2/simapp/app_di.go#L100-L270

View File

@ -29,7 +29,7 @@ Namely, the SDK provides the following mempools:
* [Sender Nonce Mempool](#sender-nonce-mempool)
* [Priority Nonce Mempool](#priority-nonce-mempool)
The default SDK is a [No-op Mempool](#no-op-mempool), but it can be replaced by the application developer in [`app.go`](./01-app-go-v2.md):
By default, the SDK uses the [No-op Mempool](#no-op-mempool), but it can be replaced by the application developer in [`app.go`](./01-app-go-di.md):
```go
nonceMempool := mempool.NewSenderNonceMempool()

View File

@ -121,4 +121,4 @@ The module is now ready to be used with `depinject` by a chain developer.
## Integrate in an application
The App Wiring is done in `app_config.go` / `app.yaml` and `app_v2.go` and is explained in detail in the [overview of `app_v2.go`](../building-apps/01-app-go-v2.md).
The App Wiring is done in `app_config.go` / `app.yaml` and `app_v2.go` and is explained in detail in the [overview of `app_v2.go`](../building-apps/01-app-go-di.md).

View File

@ -50,17 +50,17 @@ In general, the core of the state-machine is defined in a file called `app.go`.
The first thing defined in `app.go` is the `type` of the application. It is generally comprised of the following parts:
* **A reference to [`baseapp`](../advanced/00-baseapp.md).** The custom application defined in `app.go` is an extension of `baseapp`. When a transaction is relayed by CometBFT to the application, `app` uses `baseapp`'s methods to route them to the appropriate module. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://docs.cometbft.com/v0.37/spec/abci/) and the [routing logic](../advanced/00-baseapp.md#routing).
* **A list of store keys**. The [store](../advanced/04-store.md), which contains the entire state, is implemented as a [`multistore`](../advanced/04-store.md#multistore) (i.e. a store of stores) in the Cosmos SDK. Each module uses one or multiple stores in the multistore to persist their part of the state. These stores can be accessed with specific keys that are declared in the `app` type. These keys, along with the `keepers`, are at the heart of the [object-capabilities model](../advanced/10-ocap.md) of the Cosmos SDK.
* **A list of module's `keeper`s.** Each module defines an abstraction called [`keeper`](../../build/building-modules/06-keeper.md), which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type and exported as interfaces to other modules so that the latter can only access the authorized functions.
* **Embeding [runtime.App](../../build/building-apps/00-runtime.md)** The runtime package manages the application's core components and modules through dependency injection. It provides declarative configuration for module management, state storage, and ABCI handling.
* `Runtime` wraps `BaseApp`, meaning when a transaction is relayed by CometBFT to the application, `app` uses `runtime`'s methods to route them to the appropriate module. `BaseApp` implements all the [ABCI methods](https://docs.cometbft.com/v0.38/spec/abci/) and the [routing logic](../advanced/00-baseapp.md#service-routers).
* It automatically configures the **[module manager](../../build/building-modules/01-module-manager.md#manager)** based on the app wiring configuration. The module manager facilitates operations related to these modules, like registering their [`Msg` service](../../build/building-modules/03-msg-services.md) and [gRPC `Query` service](#grpc-query-services), or setting the order of execution between modules for various functions like [`InitChainer`](#initchainer), [`PreBlocker`](#preblocker) and [`BeginBlocker` and `EndBlocker`](#beginblocker-and-endblocker).
* [**An App Wiring configuration file**](../../build/building-apps/00-runtime.md) The app wiring configuration file contains the list of application's modules that `runtime` must instantiate. The instantiation of the modules are done using `depinject`. It also contains the order in which all module's `InitGenesis` and `Pre/Begin/EndBlocker` methods should be executed.
* **A reference to an [`appCodec`](../advanced/05-encoding.md).** The application's `appCodec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The default codec is [Protocol Buffers](../advanced/05-encoding.md).
* **A reference to a [`legacyAmino`](../advanced/05-encoding.md) codec.** Some parts of the Cosmos SDK have not been migrated to use the `appCodec` above, and are still hardcoded to use Amino. Other parts explicitly use Amino for backwards compatibility. For these reasons, the application still holds a reference to the legacy Amino codec. Please note that the Amino codec will be removed from the SDK in the upcoming releases.
* **A reference to a [module manager](../../build/building-modules/01-module-manager.md#manager)** and a [basic module manager](../../build/building-modules/01-module-manager.md#basicmanager). The module manager is an object that contains a list of the application's modules. It facilitates operations related to these modules, like registering their [`Msg` service](../advanced/00-baseapp.md#msg-services) and [gRPC `Query` service](../advanced/00-baseapp.md#grpc-query-services), or setting the order of execution between modules for various functions like [`InitChainer`](#initchainer), [`PreBlocker`](#preblocker) and [`BeginBlocker` and `EndBlocker`](#beginblocker-and-endblocker).
See an example of application type definition from `simapp`, the Cosmos SDK's own app used for demo and testing purposes:
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/simapp/app.go#L173-L212
https://github.com/cosmos/cosmos-sdk/blob/v0.53.0-rc.2/simapp/app_di.go#L57-L90
```
### Constructor Function

View File

@ -3,6 +3,7 @@ package runtime
import (
"fmt"
"os"
"slices"
"github.com/cosmos/gogoproto/proto"
"google.golang.org/protobuf/reflect/protodesc"
@ -199,6 +200,10 @@ func storeKeyOverride(config *runtimev1alpha1.Module, moduleName string) *runtim
}
func ProvideKVStoreKey(config *runtimev1alpha1.Module, key depinject.ModuleKey, app *AppBuilder) *storetypes.KVStoreKey {
if slices.Contains(config.SkipStoreKeys, key.Name()) {
return nil
}
override := storeKeyOverride(config, key.Name())
var storeKeyName string
@ -213,13 +218,21 @@ func ProvideKVStoreKey(config *runtimev1alpha1.Module, key depinject.ModuleKey,
return storeKey
}
func ProvideTransientStoreKey(key depinject.ModuleKey, app *AppBuilder) *storetypes.TransientStoreKey {
func ProvideTransientStoreKey(config *runtimev1alpha1.Module, key depinject.ModuleKey, app *AppBuilder) *storetypes.TransientStoreKey {
if slices.Contains(config.SkipStoreKeys, key.Name()) {
return nil
}
storeKey := storetypes.NewTransientStoreKey(fmt.Sprintf("transient:%s", key.Name()))
registerStoreKey(app, storeKey)
return storeKey
}
func ProvideMemoryStoreKey(key depinject.ModuleKey, app *AppBuilder) *storetypes.MemoryStoreKey {
func ProvideMemoryStoreKey(config *runtimev1alpha1.Module, key depinject.ModuleKey, app *AppBuilder) *storetypes.MemoryStoreKey {
if slices.Contains(config.SkipStoreKeys, key.Name()) {
return nil
}
storeKey := storetypes.NewMemoryStoreKey(fmt.Sprintf("memory:%s", key.Name()))
registerStoreKey(app, storeKey)
return storeKey
@ -234,13 +247,13 @@ func ProvideKVStoreService(config *runtimev1alpha1.Module, key depinject.ModuleK
return kvStoreService{key: storeKey}
}
func ProvideMemoryStoreService(key depinject.ModuleKey, app *AppBuilder) store.MemoryStoreService {
storeKey := ProvideMemoryStoreKey(key, app)
func ProvideMemoryStoreService(config *runtimev1alpha1.Module, key depinject.ModuleKey, app *AppBuilder) store.MemoryStoreService {
storeKey := ProvideMemoryStoreKey(config, key, app)
return memStoreService{key: storeKey}
}
func ProvideTransientStoreService(key depinject.ModuleKey, app *AppBuilder) store.TransientStoreService {
storeKey := ProvideTransientStoreKey(key, app)
func ProvideTransientStoreService(config *runtimev1alpha1.Module, key depinject.ModuleKey, app *AppBuilder) store.TransientStoreService {
storeKey := ProvideTransientStoreKey(config, key, app)
return transientStoreService{key: storeKey}
}

View File

@ -136,6 +136,9 @@ var (
KvStoreKey: "acc",
},
},
SkipStoreKeys: []string{
"tx",
},
// NOTE: The genutils module must occur after staking so that pools are
// properly initialized with tokens from genesis accounts.
// NOTE: The genutils module must also occur after auth so that it can access the params from auth.