|
| 1 | +package app |
| 2 | + |
| 3 | +import ( |
| 4 | + _ "embed" |
| 5 | + "io" |
| 6 | + "os" |
| 7 | + "path/filepath" |
| 8 | + "time" |
| 9 | + |
| 10 | + dbm "github.com/cosmos/cosmos-db" |
| 11 | + |
| 12 | + "cosmossdk.io/core/appconfig" |
| 13 | + "cosmossdk.io/depinject" |
| 14 | + "cosmossdk.io/log" |
| 15 | + |
| 16 | + storetypes "cosmossdk.io/store/types" |
| 17 | + |
| 18 | + "github.com/cosmos/cosmos-sdk/baseapp" |
| 19 | + "github.com/cosmos/cosmos-sdk/client" |
| 20 | + "github.com/cosmos/cosmos-sdk/codec" |
| 21 | + codectypes "github.com/cosmos/cosmos-sdk/codec/types" |
| 22 | + "github.com/cosmos/cosmos-sdk/runtime" |
| 23 | + "github.com/cosmos/cosmos-sdk/server" |
| 24 | + "github.com/cosmos/cosmos-sdk/server/api" |
| 25 | + "github.com/cosmos/cosmos-sdk/server/config" |
| 26 | + servertypes "github.com/cosmos/cosmos-sdk/server/types" |
| 27 | + "github.com/cosmos/cosmos-sdk/types/module" |
| 28 | + authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" |
| 29 | + bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" |
| 30 | + consensuskeeper "github.com/cosmos/cosmos-sdk/x/consensus/keeper" |
| 31 | + distrkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper" |
| 32 | + "github.com/cosmos/cosmos-sdk/x/genutil" |
| 33 | + genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" |
| 34 | + stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" |
| 35 | + oracle_abci "github.com/cosmos/sdk-tutorials/tutorials/oracle/base/x/oracle/abci" |
| 36 | + oraclekeeper "github.com/cosmos/sdk-tutorials/tutorials/oracle/base/x/oracle/keeper" |
| 37 | + "github.com/cosmos/sdk-tutorials/tutorials/oracle/base/x/oracle/mockprovider" |
| 38 | + |
| 39 | + _ "cosmossdk.io/api/cosmos/tx/config/v1" // import for side-effects |
| 40 | + _ "github.com/cosmos/cosmos-sdk/x/auth" // import for side-effects |
| 41 | + _ "github.com/cosmos/cosmos-sdk/x/auth/tx/config" // import for side-effects |
| 42 | + _ "github.com/cosmos/cosmos-sdk/x/bank" // import for side-effects |
| 43 | + _ "github.com/cosmos/cosmos-sdk/x/consensus" // import for side-effects |
| 44 | + _ "github.com/cosmos/cosmos-sdk/x/distribution" // import for side-effects |
| 45 | + _ "github.com/cosmos/cosmos-sdk/x/mint" // import for side-effects |
| 46 | + _ "github.com/cosmos/sdk-tutorials/tutorials/oracle/base/x/oracle/module" // import for side-effects |
| 47 | +) |
| 48 | + |
| 49 | +// DefaultNodeHome default home directories for the application daemon |
| 50 | +var DefaultNodeHome string |
| 51 | + |
| 52 | +//go:embed app.yaml |
| 53 | +var AppConfigYAML []byte |
| 54 | + |
| 55 | +var ( |
| 56 | + _ runtime.AppI = (*TutorialApp)(nil) |
| 57 | + _ servertypes.Application = (*TutorialApp)(nil) |
| 58 | +) |
| 59 | + |
| 60 | +// TutorialApp extends an ABCI application, but with most of its parameters exported. |
| 61 | +// They are exported for convenience in creating helper functions, as object |
| 62 | +// capabilities aren't needed for testing. |
| 63 | +type TutorialApp struct { |
| 64 | + *runtime.App |
| 65 | + legacyAmino *codec.LegacyAmino |
| 66 | + appCodec codec.Codec |
| 67 | + txConfig client.TxConfig |
| 68 | + interfaceRegistry codectypes.InterfaceRegistry |
| 69 | + |
| 70 | + // keepers |
| 71 | + AccountKeeper authkeeper.AccountKeeper |
| 72 | + BankKeeper bankkeeper.Keeper |
| 73 | + StakingKeeper *stakingkeeper.Keeper |
| 74 | + DistrKeeper distrkeeper.Keeper |
| 75 | + ConsensusParamsKeeper consensuskeeper.Keeper |
| 76 | + OracleKeeper oraclekeeper.Keeper |
| 77 | + |
| 78 | + // simulation manager |
| 79 | + sm *module.SimulationManager |
| 80 | +} |
| 81 | + |
| 82 | +func init() { |
| 83 | + userHomeDir, err := os.UserHomeDir() |
| 84 | + if err != nil { |
| 85 | + panic(err) |
| 86 | + } |
| 87 | + |
| 88 | + DefaultNodeHome = filepath.Join(userHomeDir, ".tutoriald") |
| 89 | +} |
| 90 | + |
| 91 | +// AppConfig returns the default app config. |
| 92 | +func AppConfig() depinject.Config { |
| 93 | + return depinject.Configs( |
| 94 | + appconfig.LoadYAML(AppConfigYAML), |
| 95 | + depinject.Supply( |
| 96 | + // supply custom module basics |
| 97 | + map[string]module.AppModuleBasic{ |
| 98 | + genutiltypes.ModuleName: genutil.NewAppModuleBasic(genutiltypes.DefaultMessageValidator), |
| 99 | + }, |
| 100 | + ), |
| 101 | + ) |
| 102 | +} |
| 103 | + |
| 104 | +// NewTutorialApp returns a reference to an initialized TutorialApp. |
| 105 | +func NewTutorialApp( |
| 106 | + logger log.Logger, |
| 107 | + db dbm.DB, |
| 108 | + traceStore io.Writer, |
| 109 | + loadLatest bool, |
| 110 | + appOpts servertypes.AppOptions, |
| 111 | + baseAppOptions ...func(*baseapp.BaseApp), |
| 112 | +) (*TutorialApp, error) { |
| 113 | + var ( |
| 114 | + app = &TutorialApp{} |
| 115 | + appBuilder *runtime.AppBuilder |
| 116 | + ) |
| 117 | + |
| 118 | + if err := depinject.Inject( |
| 119 | + depinject.Configs( |
| 120 | + AppConfig(), |
| 121 | + depinject.Supply( |
| 122 | + logger, |
| 123 | + appOpts, |
| 124 | + ), |
| 125 | + ), |
| 126 | + &appBuilder, |
| 127 | + &app.appCodec, |
| 128 | + &app.legacyAmino, |
| 129 | + &app.txConfig, |
| 130 | + &app.interfaceRegistry, |
| 131 | + &app.AccountKeeper, |
| 132 | + &app.BankKeeper, |
| 133 | + &app.StakingKeeper, |
| 134 | + &app.DistrKeeper, |
| 135 | + &app.ConsensusParamsKeeper, |
| 136 | + &app.OracleKeeper, |
| 137 | + ); err != nil { |
| 138 | + return nil, err |
| 139 | + } |
| 140 | + |
| 141 | + voteExtHandler := oracle_abci.NewVoteExtHandler( |
| 142 | + logger, |
| 143 | + time.Second, |
| 144 | + map[string]oracle_abci.Provider{ |
| 145 | + "mock": mockprovider.NewMockProvider(), |
| 146 | + }, |
| 147 | + map[string][]oraclekeeper.CurrencyPair{ |
| 148 | + "mock": { |
| 149 | + {Base: "ATOM", Quote: "USD"}, |
| 150 | + {Base: "OSMO", Quote: "USD"}, |
| 151 | + }, |
| 152 | + }, |
| 153 | + app.OracleKeeper, |
| 154 | + ) |
| 155 | + |
| 156 | + propHandler := oracle_abci.NewProposalHandler( |
| 157 | + logger, |
| 158 | + app.OracleKeeper, |
| 159 | + app.StakingKeeper, |
| 160 | + ) |
| 161 | + |
| 162 | + baseAppOptions = append(baseAppOptions, func(ba *baseapp.BaseApp) { |
| 163 | + ba.SetExtendVoteHandler(voteExtHandler.ExtendVoteHandler()) |
| 164 | + ba.SetVerifyVoteExtensionHandler(voteExtHandler.VerifyVoteExtensionHandler()) |
| 165 | + ba.SetPrepareProposal(propHandler.PrepareProposal()) |
| 166 | + ba.SetProcessProposal(propHandler.ProcessProposal()) |
| 167 | + ba.SetPreBlocker(propHandler.PreBlocker) |
| 168 | + }) |
| 169 | + |
| 170 | + app.App = appBuilder.Build(db, traceStore, baseAppOptions...) |
| 171 | + |
| 172 | + // register streaming services |
| 173 | + if err := app.RegisterStreamingServices(appOpts, app.kvStoreKeys()); err != nil { |
| 174 | + return nil, err |
| 175 | + } |
| 176 | + |
| 177 | + /**** Module Options ****/ |
| 178 | + |
| 179 | + // create the simulation manager and define the order of the modules for deterministic simulations |
| 180 | + // NOTE: this is not required apps that don't use the simulator for fuzz testing transactions |
| 181 | + app.sm = module.NewSimulationManagerFromAppModules(app.ModuleManager.Modules, make(map[string]module.AppModuleSimulation, 0)) |
| 182 | + app.sm.RegisterStoreDecoders() |
| 183 | + |
| 184 | + if err := app.Load(loadLatest); err != nil { |
| 185 | + return nil, err |
| 186 | + } |
| 187 | + |
| 188 | + return app, nil |
| 189 | +} |
| 190 | + |
| 191 | +// LegacyAmino returns TutorialApp's amino codec. |
| 192 | +func (app *TutorialApp) LegacyAmino() *codec.LegacyAmino { |
| 193 | + return app.legacyAmino |
| 194 | +} |
| 195 | + |
| 196 | +// GetKey returns the KVStoreKey for the provided store key. |
| 197 | +func (app *TutorialApp) GetKey(storeKey string) *storetypes.KVStoreKey { |
| 198 | + sk := app.UnsafeFindStoreKey(storeKey) |
| 199 | + kvStoreKey, ok := sk.(*storetypes.KVStoreKey) |
| 200 | + if !ok { |
| 201 | + return nil |
| 202 | + } |
| 203 | + return kvStoreKey |
| 204 | +} |
| 205 | + |
| 206 | +func (app *TutorialApp) kvStoreKeys() map[string]*storetypes.KVStoreKey { |
| 207 | + keys := make(map[string]*storetypes.KVStoreKey) |
| 208 | + for _, k := range app.GetStoreKeys() { |
| 209 | + if kv, ok := k.(*storetypes.KVStoreKey); ok { |
| 210 | + keys[kv.Name()] = kv |
| 211 | + } |
| 212 | + } |
| 213 | + |
| 214 | + return keys |
| 215 | +} |
| 216 | + |
| 217 | +// SimulationManager implements the SimulationApp interface |
| 218 | +func (app *TutorialApp) SimulationManager() *module.SimulationManager { |
| 219 | + return app.sm |
| 220 | +} |
| 221 | + |
| 222 | +// RegisterAPIRoutes registers all application module routes with the provided |
| 223 | +// API server. |
| 224 | +func (app *TutorialApp) RegisterAPIRoutes(apiSvr *api.Server, apiConfig config.APIConfig) { |
| 225 | + app.App.RegisterAPIRoutes(apiSvr, apiConfig) |
| 226 | + // register swagger API in app.go so that other applications can override easily |
| 227 | + if err := server.RegisterSwaggerAPI(apiSvr.ClientCtx, apiSvr.Router, apiConfig.Swagger); err != nil { |
| 228 | + panic(err) |
| 229 | + } |
| 230 | +} |
0 commit comments