11package runtime
22
33import (
4+ "context"
45 "encoding/json"
6+ "errors"
7+ "fmt"
8+ "io"
59
610 runtimev2 "cosmossdk.io/api/cosmos/app/runtime/v2"
711 appmodulev2 "cosmossdk.io/core/appmodule/v2"
812 "cosmossdk.io/core/registry"
13+ "cosmossdk.io/core/store"
914 "cosmossdk.io/core/transaction"
1015 "cosmossdk.io/log"
16+ "cosmossdk.io/runtime/v2/services"
1117 "cosmossdk.io/schema/decoding"
1218 "cosmossdk.io/server/v2/appmanager"
1319 "cosmossdk.io/server/v2/stf"
@@ -23,26 +29,80 @@ import (
2329// done declaratively with an app config and the rest of it is done the old way.
2430// See simapp/app_v2.go for an example of this setup.
2531type App [T transaction.Tx ] struct {
26- * appmanager.AppManager [T ]
32+ // app configuration
33+ logger log.Logger
34+ config * runtimev2.Module
2735
28- // app manager dependencies
36+ // state
2937 stf * stf.STF [T ]
3038 msgRouterBuilder * stf.MsgRouterBuilder
3139 queryRouterBuilder * stf.MsgRouterBuilder
40+ appm * appmanager.AppManager [T ]
41+ branch func (state store.ReaderMap ) store.WriterMap
3242 db Store
43+ storeLoader StoreLoader
3344
34- // app configuration
35- logger log.Logger
36- config * runtimev2.Module
37-
45+ // modules
3846 interfaceRegistrar registry.InterfaceRegistrar
3947 amino registry.AminoRegistrar
4048 moduleManager * MM [T ]
49+ queryHandlers map [string ]appmodulev2.Handler // queryHandlers defines the query handlers
50+ }
51+
52+ // initGenesis initializes the genesis state of the application.
53+ func (a * App [T ]) initGenesis (ctx context.Context , src io.Reader , txHandler func (json.RawMessage ) error ) (store.WriterMap , error ) {
54+ // this implementation assumes that the state is a JSON object
55+ bz , err := io .ReadAll (src )
56+ if err != nil {
57+ return nil , fmt .Errorf ("failed to read import state: %w" , err )
58+ }
59+ var genesisJSON map [string ]json.RawMessage
60+ if err = json .Unmarshal (bz , & genesisJSON ); err != nil {
61+ return nil , err
62+ }
63+
64+ v , zeroState , err := a .db .StateLatest ()
65+ if err != nil {
66+ return nil , fmt .Errorf ("unable to get latest state: %w" , err )
67+ }
68+ if v != 0 { // TODO: genesis state may be > 0, we need to set version on store
69+ return nil , errors .New ("cannot init genesis on non-zero state" )
70+ }
71+ genesisCtx := services .NewGenesisContext (a .branch (zeroState ))
72+ genesisState , err := genesisCtx .Mutate (ctx , func (ctx context.Context ) error {
73+ err = a .moduleManager .InitGenesisJSON (ctx , genesisJSON , txHandler )
74+ if err != nil {
75+ return fmt .Errorf ("failed to init genesis: %w" , err )
76+ }
77+ return nil
78+ })
79+
80+ return genesisState , err
81+ }
4182
42- // QueryHandlers defines the query handlers
43- QueryHandlers map [string ]appmodulev2.Handler
83+ // exportGenesis exports the genesis state of the application.
84+ func (a * App [T ]) exportGenesis (ctx context.Context , version uint64 ) ([]byte , error ) {
85+ state , err := a .db .StateAt (version )
86+ if err != nil {
87+ return nil , fmt .Errorf ("unable to get state at given version: %w" , err )
88+ }
89+
90+ genesisJson , err := a .moduleManager .ExportGenesisForModules (
91+ ctx ,
92+ func () store.WriterMap {
93+ return a .branch (state )
94+ },
95+ )
96+ if err != nil {
97+ return nil , fmt .Errorf ("failed to export genesis: %w" , err )
98+ }
99+
100+ bz , err := json .Marshal (genesisJson )
101+ if err != nil {
102+ return nil , fmt .Errorf ("failed to marshal genesis: %w" , err )
103+ }
44104
45- storeLoader StoreLoader
105+ return bz , nil
46106}
47107
48108// Name returns the app name.
@@ -85,24 +145,26 @@ func (a *App[T]) LoadLatestHeight() (uint64, error) {
85145 return a .db .GetLatestVersion ()
86146}
87147
88- // Close is called in start cmd to gracefully cleanup resources.
89- func (a * App [T ]) Close () error {
90- return nil
148+ // AppManager returns the app's appamanger
149+ func (a * App [T ]) AppManager () * appmanager. AppManager [ T ] {
150+ return a . appm
91151}
92152
93- func (a * App [T ]) GetAppManager () * appmanager.AppManager [T ] {
94- return a .AppManager
153+ // GetQueryHandlers returns the query handlers.
154+ func (a * App [T ]) QueryHandlers () map [string ]appmodulev2.Handler {
155+ return a .queryHandlers
95156}
96157
97- func (a * App [T ]) GetQueryHandlers () map [string ]appmodulev2.Handler {
98- return a .QueryHandlers
99- }
100-
101- // GetSchemaDecoderResolver returns the module schema resolver.
102- func (a * App [T ]) GetSchemaDecoderResolver () decoding.DecoderResolver {
158+ // SchemaDecoderResolver returns the module schema resolver.
159+ func (a * App [T ]) SchemaDecoderResolver () decoding.DecoderResolver {
103160 moduleSet := map [string ]any {}
104161 for moduleName , module := range a .moduleManager .Modules () {
105162 moduleSet [moduleName ] = module
106163 }
107164 return decoding .ModuleSetDecoderResolver (moduleSet )
108165}
166+
167+ // Close is called in start cmd to gracefully cleanup resources.
168+ func (a * App [T ]) Close () error {
169+ return nil
170+ }
0 commit comments