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:
type App struct {
*baseapp.BaseApp
ModuleManager *module.Manager
UnorderedTxManager *unorderedtx.Manager
configurator module.Configurator
config *runtimev1alpha1.Module
storeKeys []storetypes.StoreKey
// ... other fields
}
It is the struct that any Cosmos SDK application should embed to leverage the runtime module.
loading...
Configuration
The runtime module is configured using App Wiring. The main configuration object is the Module
message, which supports the following key settings:
app_name
: The name of the applicationbegin_blockers
: List of module names to call during BeginBlockend_blockers
: List of module names to call during EndBlockinit_genesis
: Order of module initialization during genesisexport_genesis
: Order for exporting module genesis datapre_blockers
: Modules to execute before block processing
Learn more about wiring runtime
in the next section.
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 keysskip_store_keys
: Specifies store keys to skip during keeper construction
Example configuration:
loading...
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 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
.
2. Module Registration
Runtime has built-in support for depinject
-enabled modules.
Such modules can be registered through the configuration file (often named app_config.go
), with no additional code required.
loading...
Additionally, the runtime package facilitates manual module registration through the RegisterModules
method. This is the primary integration point for modules not registered via configuration.
Even when using manual registration, the module should still be configured in the Module
message in AppConfig.
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 required by modules.
These services include the store
, the event manager
, the context
, and the logger
.
As runtime is doing the wiring of modules, it can ensure that the services are scoped to their respective modules.
loading...
Additionally, runtime provides automatic registration of other essential (f.e gRPC routes) services, available to the App:
- AutoCLI Query Service
- Reflection Service
- Custom module services
loading...
4. Application Building
The AppBuilder
type provides a structured way to build applications:
loading...
Key building steps:
- Configuration loading
- Module registration
- Service setup
- Store mounting
- Router configuration
An application only needs to call AppBuilder.Build
to create a fully configured application (runtime.App
).
loading...
More information on building applications can be found in the next section.
Best Practices
- Module Order: Carefully consider the order of modules in begin_blockers and end_blockers
- Store Keys: Use override_store_keys only when necessary to maintain clarity
- Genesis Order: Maintain correct initialization order in init_genesis
- Migration Management: Use order_migrations to control upgrade paths
Migration Considerations
When upgrading between versions:
- Review the migration order specified in
order_migrations
- Ensure all required modules are included in the configuration
- Validate store key configurations
- Test the upgrade path thoroughly