Skip to content

Commit 681366e

Browse files
authored
refactor(runtime/v2): simplify app manager (#22300)
1 parent 97d37ae commit 681366e

22 files changed

+194
-192
lines changed

runtime/v2/app.go

+19-24
Original file line numberDiff line numberDiff line change
@@ -23,26 +23,24 @@ import (
2323
// done declaratively with an app config and the rest of it is done the old way.
2424
// See simapp/app_v2.go for an example of this setup.
2525
type App[T transaction.Tx] struct {
26-
*appmanager.AppManager[T]
26+
appmanager.AppManager[T]
2727

28-
// app manager dependencies
28+
// app configuration
29+
logger log.Logger
30+
config *runtimev2.Module
31+
32+
// state
2933
stf *stf.STF[T]
3034
msgRouterBuilder *stf.MsgRouterBuilder
3135
queryRouterBuilder *stf.MsgRouterBuilder
3236
db Store
37+
storeLoader StoreLoader
3338

34-
// app configuration
35-
logger log.Logger
36-
config *runtimev2.Module
37-
39+
// modules
3840
interfaceRegistrar registry.InterfaceRegistrar
3941
amino registry.AminoRegistrar
4042
moduleManager *MM[T]
41-
42-
// QueryHandlers defines the query handlers
43-
QueryHandlers map[string]appmodulev2.Handler
44-
45-
storeLoader StoreLoader
43+
queryHandlers map[string]appmodulev2.Handler // queryHandlers defines the query handlers
4644
}
4745

4846
// Name returns the app name.
@@ -85,24 +83,21 @@ func (a *App[T]) LoadLatestHeight() (uint64, error) {
8583
return a.db.GetLatestVersion()
8684
}
8785

88-
// Close is called in start cmd to gracefully cleanup resources.
89-
func (a *App[T]) Close() error {
90-
return nil
91-
}
92-
93-
func (a *App[T]) GetAppManager() *appmanager.AppManager[T] {
94-
return a.AppManager
95-
}
96-
97-
func (a *App[T]) GetQueryHandlers() map[string]appmodulev2.Handler {
98-
return a.QueryHandlers
86+
// GetQueryHandlers returns the query handlers.
87+
func (a *App[T]) QueryHandlers() map[string]appmodulev2.Handler {
88+
return a.queryHandlers
9989
}
10090

101-
// GetSchemaDecoderResolver returns the module schema resolver.
102-
func (a *App[T]) GetSchemaDecoderResolver() decoding.DecoderResolver {
91+
// SchemaDecoderResolver returns the module schema resolver.
92+
func (a *App[T]) SchemaDecoderResolver() decoding.DecoderResolver {
10393
moduleSet := map[string]any{}
10494
for moduleName, module := range a.moduleManager.Modules() {
10595
moduleSet[moduleName] = module
10696
}
10797
return decoding.ModuleSetDecoderResolver(moduleSet)
10898
}
99+
100+
// Close is called in start cmd to gracefully cleanup resources.
101+
func (a *App[T]) Close() error {
102+
return nil
103+
}

runtime/v2/builder.go

+60-67
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,6 @@ type AppBuilder[T transaction.Tx] struct {
3131
postTxExec func(ctx context.Context, tx T, success bool) error
3232
}
3333

34-
// DefaultGenesis returns a default genesis from the registered AppModule's.
35-
func (a *AppBuilder[T]) DefaultGenesis() map[string]json.RawMessage {
36-
return a.app.moduleManager.DefaultGenesis()
37-
}
38-
3934
// RegisterModules registers the provided modules with the module manager.
4035
// This is the primary hook for integrating with modules which are not registered using the app config.
4136
func (a *AppBuilder[T]) RegisterModules(modules map[string]appmodulev2.AppModule) error {
@@ -98,7 +93,7 @@ func (a *AppBuilder[T]) Build(opts ...AppBuilderOption[T]) (*App[T], error) {
9893

9994
endBlocker, valUpdate := a.app.moduleManager.EndBlock()
10095

101-
stf, err := stf.NewSTF[T](
96+
stf, err := stf.New[T](
10297
a.app.logger.With("module", "stf"),
10398
a.app.msgRouterBuilder,
10499
a.app.queryRouterBuilder,
@@ -115,77 +110,75 @@ func (a *AppBuilder[T]) Build(opts ...AppBuilderOption[T]) (*App[T], error) {
115110
}
116111
a.app.stf = stf
117112

118-
appManagerBuilder := appmanager.Builder[T]{
119-
STF: a.app.stf,
120-
DB: a.app.db,
121-
ValidateTxGasLimit: a.app.config.GasConfig.ValidateTxGasLimit,
122-
QueryGasLimit: a.app.config.GasConfig.QueryGasLimit,
123-
SimulationGasLimit: a.app.config.GasConfig.SimulationGasLimit,
124-
InitGenesis: func(
125-
ctx context.Context,
126-
src io.Reader,
127-
txHandler func(json.RawMessage) error,
128-
) (store.WriterMap, error) {
129-
// this implementation assumes that the state is a JSON object
130-
bz, err := io.ReadAll(src)
131-
if err != nil {
132-
return nil, fmt.Errorf("failed to read import state: %w", err)
133-
}
134-
var genesisJSON map[string]json.RawMessage
135-
if err = json.Unmarshal(bz, &genesisJSON); err != nil {
136-
return nil, err
137-
}
138-
139-
v, zeroState, err := a.app.db.StateLatest()
140-
if err != nil {
141-
return nil, fmt.Errorf("unable to get latest state: %w", err)
142-
}
143-
if v != 0 { // TODO: genesis state may be > 0, we need to set version on store
144-
return nil, errors.New("cannot init genesis on non-zero state")
145-
}
146-
genesisCtx := services.NewGenesisContext(a.branch(zeroState))
147-
genesisState, err := genesisCtx.Mutate(ctx, func(ctx context.Context) error {
148-
err = a.app.moduleManager.InitGenesisJSON(ctx, genesisJSON, txHandler)
149-
if err != nil {
150-
return fmt.Errorf("failed to init genesis: %w", err)
151-
}
152-
return nil
153-
})
154-
155-
return genesisState, err
113+
a.app.AppManager = appmanager.New[T](
114+
appmanager.Config{
115+
ValidateTxGasLimit: a.app.config.GasConfig.ValidateTxGasLimit,
116+
QueryGasLimit: a.app.config.GasConfig.QueryGasLimit,
117+
SimulationGasLimit: a.app.config.GasConfig.SimulationGasLimit,
156118
},
157-
ExportGenesis: func(ctx context.Context, version uint64) ([]byte, error) {
158-
state, err := a.app.db.StateAt(version)
159-
if err != nil {
160-
return nil, fmt.Errorf("unable to get state at given version: %w", err)
161-
}
119+
a.app.db,
120+
a.app.stf,
121+
a.initGenesis,
122+
a.exportGenesis,
123+
)
162124

163-
genesisJson, err := a.app.moduleManager.ExportGenesisForModules(
164-
ctx,
165-
func() store.WriterMap {
166-
return a.branch(state)
167-
},
168-
)
169-
if err != nil {
170-
return nil, fmt.Errorf("failed to export genesis: %w", err)
171-
}
125+
return a.app, nil
126+
}
172127

173-
bz, err := json.Marshal(genesisJson)
174-
if err != nil {
175-
return nil, fmt.Errorf("failed to marshal genesis: %w", err)
176-
}
128+
// initGenesis returns the app initialization genesis for modules
129+
func (a *AppBuilder[T]) initGenesis(ctx context.Context, src io.Reader, txHandler func(json.RawMessage) error) (store.WriterMap, error) {
130+
// this implementation assumes that the state is a JSON object
131+
bz, err := io.ReadAll(src)
132+
if err != nil {
133+
return nil, fmt.Errorf("failed to read import state: %w", err)
134+
}
135+
var genesisJSON map[string]json.RawMessage
136+
if err = json.Unmarshal(bz, &genesisJSON); err != nil {
137+
return nil, err
138+
}
139+
140+
v, zeroState, err := a.app.db.StateLatest()
141+
if err != nil {
142+
return nil, fmt.Errorf("unable to get latest state: %w", err)
143+
}
144+
if v != 0 { // TODO: genesis state may be > 0, we need to set version on store
145+
return nil, errors.New("cannot init genesis on non-zero state")
146+
}
147+
genesisCtx := services.NewGenesisContext(a.branch(zeroState))
148+
genesisState, err := genesisCtx.Mutate(ctx, func(ctx context.Context) error {
149+
err = a.app.moduleManager.InitGenesisJSON(ctx, genesisJSON, txHandler)
150+
if err != nil {
151+
return fmt.Errorf("failed to init genesis: %w", err)
152+
}
153+
return nil
154+
})
177155

178-
return bz, nil
156+
return genesisState, err
157+
}
158+
159+
// exportGenesis returns the app export genesis logic for modules
160+
func (a *AppBuilder[T]) exportGenesis(ctx context.Context, version uint64) ([]byte, error) {
161+
state, err := a.app.db.StateAt(version)
162+
if err != nil {
163+
return nil, fmt.Errorf("unable to get state at given version: %w", err)
164+
}
165+
166+
genesisJson, err := a.app.moduleManager.ExportGenesisForModules(
167+
ctx,
168+
func() store.WriterMap {
169+
return a.branch(state)
179170
},
171+
)
172+
if err != nil {
173+
return nil, fmt.Errorf("failed to export genesis: %w", err)
180174
}
181175

182-
appManager, err := appManagerBuilder.Build()
176+
bz, err := json.Marshal(genesisJson)
183177
if err != nil {
184-
return nil, fmt.Errorf("failed to build app manager: %w", err)
178+
return nil, fmt.Errorf("failed to marshal genesis: %w", err)
185179
}
186-
a.app.AppManager = appManager
187180

188-
return a.app, nil
181+
return bz, nil
189182
}
190183

191184
// AppBuilderOption is a function that can be passed to AppBuilder.Build to customize the resulting app.

runtime/v2/manager.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -636,7 +636,7 @@ func registerServices[T transaction.Tx](s appmodulev2.AppModule, app *App[T], re
636636

637637
// merge maps
638638
for path, decoder := range c.queryHandlers {
639-
app.QueryHandlers[path] = decoder
639+
app.queryHandlers[path] = decoder
640640
}
641641
}
642642

@@ -655,7 +655,7 @@ func registerServices[T transaction.Tx](s appmodulev2.AppModule, app *App[T], re
655655
module.RegisterQueryHandlers(&wrapper)
656656

657657
for path, handler := range wrapper.handlers {
658-
app.QueryHandlers[path] = handler
658+
app.queryHandlers[path] = handler
659659
}
660660
}
661661

runtime/v2/module.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ func ProvideAppBuilder[T transaction.Tx](
131131
amino: amino,
132132
msgRouterBuilder: msgRouterBuilder,
133133
queryRouterBuilder: stf.NewMsgRouterBuilder(), // TODO dedicated query router
134-
QueryHandlers: map[string]appmodulev2.Handler{},
134+
queryHandlers: map[string]appmodulev2.Handler{},
135135
storeLoader: DefaultStoreLoader,
136136
}
137137
appBuilder := &AppBuilder[T]{app: app, storeBuilder: storeBuilder}

server/v2/api/grpc/server.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -57,14 +57,14 @@ func (s *Server[T]) Init(appI serverv2.AppI[T], cfg map[string]any, logger log.L
5757
return fmt.Errorf("failed to unmarshal config: %w", err)
5858
}
5959
}
60-
methodsMap := appI.GetQueryHandlers()
60+
methodsMap := appI.QueryHandlers()
6161

6262
grpcSrv := grpc.NewServer(
6363
grpc.ForceServerCodec(newProtoCodec(appI.InterfaceRegistry()).GRPCCodec()),
6464
grpc.MaxSendMsgSize(serverCfg.MaxSendMsgSize),
6565
grpc.MaxRecvMsgSize(serverCfg.MaxRecvMsgSize),
6666
grpc.UnknownServiceHandler(
67-
makeUnknownServiceHandler(methodsMap, appI.GetAppManager()),
67+
makeUnknownServiceHandler(methodsMap, appI),
6868
),
6969
)
7070

@@ -85,7 +85,7 @@ func (s *Server[T]) StartCmdFlags() *pflag.FlagSet {
8585
}
8686

8787
func makeUnknownServiceHandler(handlers map[string]appmodulev2.Handler, querier interface {
88-
Query(ctx context.Context, version uint64, msg gogoproto.Message) (gogoproto.Message, error)
88+
Query(ctx context.Context, version uint64, msg transaction.Msg) (transaction.Msg, error)
8989
},
9090
) grpc.StreamHandler {
9191
getRegistry := sync.OnceValues(gogoproto.MergedRegistry)

server/v2/api/rest/handler.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,12 @@ const (
2020
MaxBodySize = 1 << 20 // 1 MB
2121
)
2222

23-
func NewDefaultHandler[T transaction.Tx](appManager *appmanager.AppManager[T]) http.Handler {
23+
func NewDefaultHandler[T transaction.Tx](appManager appmanager.AppManager[T]) http.Handler {
2424
return &DefaultHandler[T]{appManager: appManager}
2525
}
2626

2727
type DefaultHandler[T transaction.Tx] struct {
28-
appManager *appmanager.AppManager[T]
28+
appManager appmanager.AppManager[T]
2929
}
3030

3131
func (h *DefaultHandler[T]) ServeHTTP(w http.ResponseWriter, r *http.Request) {

server/v2/api/rest/server.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ func (s *Server[T]) Init(appI serverv2.AppI[T], cfg map[string]any, logger log.L
4545
}
4646

4747
s.router = http.NewServeMux()
48-
s.router.Handle("/", NewDefaultHandler(appI.GetAppManager()))
48+
s.router.Handle("/", NewDefaultHandler(appI))
4949
s.config = serverCfg
5050

5151
return nil

0 commit comments

Comments
 (0)