|
|
|
@@ -33,6 +33,7 @@ import (
|
|
|
|
|
"fmt"
|
|
|
|
|
"sort"
|
|
|
|
|
|
|
|
|
|
"cosmossdk.io/core/appmodule"
|
|
|
|
|
"github.com/grpc-ecosystem/grpc-gateway/runtime"
|
|
|
|
|
"github.com/spf13/cobra"
|
|
|
|
|
abci "github.com/tendermint/tendermint/abci/types"
|
|
|
|
@@ -47,12 +48,11 @@ import (
|
|
|
|
|
|
|
|
|
|
// AppModuleBasic is the standard form for basic non-dependant elements of an application module.
|
|
|
|
|
type AppModuleBasic interface {
|
|
|
|
|
Name() string
|
|
|
|
|
HasName
|
|
|
|
|
RegisterLegacyAminoCodec(*codec.LegacyAmino)
|
|
|
|
|
RegisterInterfaces(codectypes.InterfaceRegistry)
|
|
|
|
|
|
|
|
|
|
DefaultGenesis(codec.JSONCodec) json.RawMessage
|
|
|
|
|
ValidateGenesis(codec.JSONCodec, client.TxEncodingConfig, json.RawMessage) error
|
|
|
|
|
HasGenesisBasics
|
|
|
|
|
|
|
|
|
|
// client functionality
|
|
|
|
|
RegisterGRPCGatewayRoutes(client.Context, *runtime.ServeMux)
|
|
|
|
@@ -60,6 +60,19 @@ type AppModuleBasic interface {
|
|
|
|
|
GetQueryCmd() *cobra.Command
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// HasName allows the module to provide its own name for legacy purposes.
|
|
|
|
|
// Newer apps should specify the name for their modules using a map
|
|
|
|
|
// using NewManagerFromMap.
|
|
|
|
|
type HasName interface {
|
|
|
|
|
Name() string
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// HasGenesisBasics is the legacy interface for stateless genesis methods.
|
|
|
|
|
type HasGenesisBasics interface {
|
|
|
|
|
DefaultGenesis(codec.JSONCodec) json.RawMessage
|
|
|
|
|
ValidateGenesis(codec.JSONCodec, client.TxEncodingConfig, json.RawMessage) error
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// BasicManager is a collection of AppModuleBasic
|
|
|
|
|
type BasicManager map[string]AppModuleBasic
|
|
|
|
|
|
|
|
|
@@ -143,21 +156,36 @@ func (bm BasicManager) AddQueryCommands(rootQueryCmd *cobra.Command) {
|
|
|
|
|
// AppModuleGenesis is the standard form for an application module genesis functions
|
|
|
|
|
type AppModuleGenesis interface {
|
|
|
|
|
AppModuleBasic
|
|
|
|
|
HasGenesis
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// HasGenesis is the extension interface for stateful genesis methods.
|
|
|
|
|
type HasGenesis interface {
|
|
|
|
|
HasGenesisBasics
|
|
|
|
|
InitGenesis(sdk.Context, codec.JSONCodec, json.RawMessage) []abci.ValidatorUpdate
|
|
|
|
|
ExportGenesis(sdk.Context, codec.JSONCodec) json.RawMessage
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// AppModule is the standard form for an application module
|
|
|
|
|
// AppModule is the form for an application module. Most of
|
|
|
|
|
// its functionality has been moved to extension interfaces.
|
|
|
|
|
type AppModule interface {
|
|
|
|
|
AppModuleGenesis
|
|
|
|
|
AppModuleBasic
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// registers
|
|
|
|
|
// HasInvariants is the interface for registering invariants.
|
|
|
|
|
type HasInvariants interface {
|
|
|
|
|
// RegisterInvariants registers module invariants.
|
|
|
|
|
RegisterInvariants(sdk.InvariantRegistry)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// RegisterServices allows a module to register services
|
|
|
|
|
// HasServices is the interface for modules to register services.
|
|
|
|
|
type HasServices interface {
|
|
|
|
|
// RegisterServices allows a module to register services.
|
|
|
|
|
RegisterServices(Configurator)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// HasConsensusVersion is the interface for declaring a module consensus version.
|
|
|
|
|
type HasConsensusVersion interface {
|
|
|
|
|
// ConsensusVersion is a sequence number for state-breaking change of the
|
|
|
|
|
// module. It should be incremented on each consensus-breaking change
|
|
|
|
|
// introduced by the module. To avoid wrong/empty versions, the initial version
|
|
|
|
@@ -183,12 +211,18 @@ type GenesisOnlyAppModule struct {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// NewGenesisOnlyAppModule creates a new GenesisOnlyAppModule object
|
|
|
|
|
func NewGenesisOnlyAppModule(amg AppModuleGenesis) AppModule {
|
|
|
|
|
func NewGenesisOnlyAppModule(amg AppModuleGenesis) GenesisOnlyAppModule {
|
|
|
|
|
return GenesisOnlyAppModule{
|
|
|
|
|
AppModuleGenesis: amg,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// IsOnePerModuleType implements the depinject.OnePerModuleType interface.
|
|
|
|
|
func (GenesisOnlyAppModule) IsOnePerModuleType() {}
|
|
|
|
|
|
|
|
|
|
// IsAppModule implements the appmodule.AppModule interface.
|
|
|
|
|
func (GenesisOnlyAppModule) IsAppModule() {}
|
|
|
|
|
|
|
|
|
|
// RegisterInvariants is a placeholder function register no invariants
|
|
|
|
|
func (GenesisOnlyAppModule) RegisterInvariants(_ sdk.InvariantRegistry) {}
|
|
|
|
|
|
|
|
|
@@ -212,7 +246,7 @@ func (GenesisOnlyAppModule) EndBlock(_ sdk.Context, _ abci.RequestEndBlock) []ab
|
|
|
|
|
// Manager defines a module manager that provides the high level utility for managing and executing
|
|
|
|
|
// operations for a group of modules
|
|
|
|
|
type Manager struct {
|
|
|
|
|
Modules map[string]AppModule
|
|
|
|
|
Modules map[string]interface{} // interface{} is used now to support the legacy AppModule as well as new core appmodule.AppModule.
|
|
|
|
|
OrderInitGenesis []string
|
|
|
|
|
OrderExportGenesis []string
|
|
|
|
|
OrderBeginBlockers []string
|
|
|
|
@@ -220,9 +254,9 @@ type Manager struct {
|
|
|
|
|
OrderMigrations []string
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// NewManager creates a new Manager object
|
|
|
|
|
// NewManager creates a new Manager object.
|
|
|
|
|
func NewManager(modules ...AppModule) *Manager {
|
|
|
|
|
moduleMap := make(map[string]AppModule)
|
|
|
|
|
moduleMap := make(map[string]interface{})
|
|
|
|
|
modulesStr := make([]string, 0, len(modules))
|
|
|
|
|
for _, module := range modules {
|
|
|
|
|
moduleMap[module.Name()] = module
|
|
|
|
@@ -238,6 +272,25 @@ func NewManager(modules ...AppModule) *Manager {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// NewManagerFromMap creates a new Manager object from a map of module names to module implementations.
|
|
|
|
|
// This method should be used for apps and modules which have migrated to the cosmossdk.io/core.appmodule.AppModule API.
|
|
|
|
|
func NewManagerFromMap(moduleMap map[string]appmodule.AppModule) *Manager {
|
|
|
|
|
simpleModuleMap := make(map[string]interface{})
|
|
|
|
|
modulesStr := make([]string, 0, len(simpleModuleMap))
|
|
|
|
|
for name, module := range moduleMap {
|
|
|
|
|
simpleModuleMap[name] = module
|
|
|
|
|
modulesStr = append(modulesStr, name)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return &Manager{
|
|
|
|
|
Modules: simpleModuleMap,
|
|
|
|
|
OrderInitGenesis: modulesStr,
|
|
|
|
|
OrderExportGenesis: modulesStr,
|
|
|
|
|
OrderBeginBlockers: modulesStr,
|
|
|
|
|
OrderEndBlockers: modulesStr,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// SetOrderInitGenesis sets the order of init genesis calls
|
|
|
|
|
func (m *Manager) SetOrderInitGenesis(moduleNames ...string) {
|
|
|
|
|
m.assertNoForgottenModules("SetOrderInitGenesis", moduleNames)
|
|
|
|
@@ -273,7 +326,9 @@ func (m *Manager) SetOrderMigrations(moduleNames ...string) {
|
|
|
|
|
func (m *Manager) RegisterInvariants(ir sdk.InvariantRegistry) {
|
|
|
|
|
modules := maps.Values(m.Modules)
|
|
|
|
|
for _, module := range modules {
|
|
|
|
|
module.RegisterInvariants(ir)
|
|
|
|
|
if module, ok := module.(HasInvariants); ok {
|
|
|
|
|
module.RegisterInvariants(ir)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -281,7 +336,9 @@ func (m *Manager) RegisterInvariants(ir sdk.InvariantRegistry) {
|
|
|
|
|
func (m *Manager) RegisterServices(cfg Configurator) {
|
|
|
|
|
modules := maps.Values(m.Modules)
|
|
|
|
|
for _, module := range modules {
|
|
|
|
|
module.RegisterServices(cfg)
|
|
|
|
|
if module, ok := module.(HasServices); ok {
|
|
|
|
|
module.RegisterServices(cfg)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -295,17 +352,20 @@ func (m *Manager) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, genesisData
|
|
|
|
|
if genesisData[moduleName] == nil {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
ctx.Logger().Debug("running initialization for module", "module", moduleName)
|
|
|
|
|
|
|
|
|
|
moduleValUpdates := m.Modules[moduleName].InitGenesis(ctx, cdc, genesisData[moduleName])
|
|
|
|
|
if module, ok := m.Modules[moduleName].(HasGenesis); ok {
|
|
|
|
|
ctx.Logger().Debug("running initialization for module", "module", moduleName)
|
|
|
|
|
|
|
|
|
|
// use these validator updates if provided, the module manager assumes
|
|
|
|
|
// only one module will update the validator set
|
|
|
|
|
if len(moduleValUpdates) > 0 {
|
|
|
|
|
if len(validatorUpdates) > 0 {
|
|
|
|
|
panic("validator InitGenesis updates already set by a previous module")
|
|
|
|
|
moduleValUpdates := module.InitGenesis(ctx, cdc, genesisData[moduleName])
|
|
|
|
|
|
|
|
|
|
// use these validator updates if provided, the module manager assumes
|
|
|
|
|
// only one module will update the validator set
|
|
|
|
|
if len(moduleValUpdates) > 0 {
|
|
|
|
|
if len(validatorUpdates) > 0 {
|
|
|
|
|
panic("validator InitGenesis updates already set by a previous module")
|
|
|
|
|
}
|
|
|
|
|
validatorUpdates = moduleValUpdates
|
|
|
|
|
}
|
|
|
|
|
validatorUpdates = moduleValUpdates
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -329,7 +389,9 @@ func (m *Manager) ExportGenesisForModules(ctx sdk.Context, cdc codec.JSONCodec,
|
|
|
|
|
genesisData := make(map[string]json.RawMessage)
|
|
|
|
|
if len(modulesToExport) == 0 {
|
|
|
|
|
for _, moduleName := range m.OrderExportGenesis {
|
|
|
|
|
genesisData[moduleName] = m.Modules[moduleName].ExportGenesis(ctx, cdc)
|
|
|
|
|
if module, ok := m.Modules[moduleName].(HasGenesis); ok {
|
|
|
|
|
genesisData[moduleName] = module.ExportGenesis(ctx, cdc)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return genesisData
|
|
|
|
@@ -341,7 +403,9 @@ func (m *Manager) ExportGenesisForModules(ctx sdk.Context, cdc codec.JSONCodec,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for _, moduleName := range modulesToExport {
|
|
|
|
|
genesisData[moduleName] = m.Modules[moduleName].ExportGenesis(ctx, cdc)
|
|
|
|
|
if module, ok := m.Modules[moduleName].(HasGenesis); ok {
|
|
|
|
|
genesisData[moduleName] = module.ExportGenesis(ctx, cdc)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return genesisData
|
|
|
|
@@ -450,7 +514,10 @@ func (m Manager) RunMigrations(ctx sdk.Context, cfg Configurator, fromVM Version
|
|
|
|
|
for _, moduleName := range modules {
|
|
|
|
|
module := m.Modules[moduleName]
|
|
|
|
|
fromVersion, exists := fromVM[moduleName]
|
|
|
|
|
toVersion := module.ConsensusVersion()
|
|
|
|
|
toVersion := uint64(0)
|
|
|
|
|
if module, ok := module.(HasConsensusVersion); ok {
|
|
|
|
|
toVersion = module.ConsensusVersion()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// We run migration if the module is specified in `fromVM`.
|
|
|
|
|
// Otherwise we run InitGenesis.
|
|
|
|
@@ -467,11 +534,13 @@ func (m Manager) RunMigrations(ctx sdk.Context, cfg Configurator, fromVM Version
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
ctx.Logger().Info(fmt.Sprintf("adding a new module: %s", moduleName))
|
|
|
|
|
moduleValUpdates := module.InitGenesis(ctx, c.cdc, module.DefaultGenesis(c.cdc))
|
|
|
|
|
// The module manager assumes only one module will update the
|
|
|
|
|
// validator set, and it can't be a new module.
|
|
|
|
|
if len(moduleValUpdates) > 0 {
|
|
|
|
|
return nil, sdkerrors.Wrapf(sdkerrors.ErrLogic, "validator InitGenesis update is already set by another module")
|
|
|
|
|
if module, ok := m.Modules[moduleName].(HasGenesis); ok {
|
|
|
|
|
moduleValUpdates := module.InitGenesis(ctx, c.cdc, module.DefaultGenesis(c.cdc))
|
|
|
|
|
// The module manager assumes only one module will update the
|
|
|
|
|
// validator set, and it can't be a new module.
|
|
|
|
|
if len(moduleValUpdates) > 0 {
|
|
|
|
|
return nil, sdkerrors.Wrapf(sdkerrors.ErrLogic, "validator InitGenesis update is already set by another module")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -533,9 +602,12 @@ func (m *Manager) EndBlock(ctx sdk.Context, req abci.RequestEndBlock) abci.Respo
|
|
|
|
|
// GetVersionMap gets consensus version from all modules
|
|
|
|
|
func (m *Manager) GetVersionMap() VersionMap {
|
|
|
|
|
vermap := make(VersionMap)
|
|
|
|
|
for _, v := range m.Modules {
|
|
|
|
|
version := v.ConsensusVersion()
|
|
|
|
|
name := v.Name()
|
|
|
|
|
for name, v := range m.Modules {
|
|
|
|
|
version := uint64(0)
|
|
|
|
|
if v, ok := v.(HasConsensusVersion); ok {
|
|
|
|
|
version = v.ConsensusVersion()
|
|
|
|
|
}
|
|
|
|
|
name := name
|
|
|
|
|
vermap[name] = version
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|