cosmos-sdk/server/README.md

112 lines
4.6 KiB
Markdown
Raw Normal View History

2020-07-21 08:28:43 -07:00
# Server
The `server` package is responsible for providing the mechanisms necessary to
start an ABCI Tendermint application and provides the CLI framework (based on [cobra](github.com/spf13/cobra))
necessary to fully bootstrap an application. The package exposes two core functions: `StartCmd`
and `ExportCmd` which creates commands to start the application and export state respectively.
2020-07-21 08:28:43 -07:00
## Preliminary
The root command of an application typically is constructed with:
docs: Improve markdownlint configuration (#11104) ## Description Closes: #9404 --- ### Author Checklist *All items are required. Please add a note to the item if the item is not applicable and please add links to any relevant follow up issues.* I have... - [x] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] added `!` to the type prefix if API or client breaking change - [x] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#pr-targeting)) - [x] provided a link to the relevant issue or specification - [ ] followed the guidelines for [building modules](https://github.com/cosmos/cosmos-sdk/blob/master/docs/building-modules) - [ ] included the necessary unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#testing) - [ ] added a changelog entry to `CHANGELOG.md` - [ ] included comments for [documenting Go code](https://blog.golang.org/godoc) - [ ] updated the relevant documentation or specification - [x] reviewed "Files changed" and left comments if necessary - [x] confirmed all CI checks have passed ### Reviewers Checklist *All items are required. Please add a note if the item is not applicable and please add your handle next to the items reviewed if you only reviewed selected items.* I have... - [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] confirmed `!` in the type prefix if API or client breaking change - [ ] confirmed all author checklist items have been addressed - [ ] reviewed state machine logic - [ ] reviewed API design and naming - [ ] reviewed documentation is accurate - [ ] reviewed tests and test coverage - [ ] manually tested (if applicable)
2022-02-10 04:07:01 -08:00
* command to start an application binary
* three meta commands: `query`, `tx`, and a few auxiliary commands such as `genesis`.
utilities.
2020-07-21 08:28:43 -07:00
It is vital that the root command of an application uses `PersistentPreRun()` cobra command
property for executing the command, so all child commands have access to the server and client contexts.
2020-07-21 08:28:43 -07:00
These contexts are set as their default values initially and maybe modified,
scoped to the command, in their respective `PersistentPreRun()` functions. Note that
2020-07-21 08:28:43 -07:00
the `client.Context` is typically pre-populated with "default" values that may be
useful for all commands to inherit and override if necessary.
Example:
```go
var (
initClientCtx = client.Context{...}
2020-07-21 08:28:43 -07:00
rootCmd = &cobra.Command{
Use: "simd",
Short: "simulation app",
PersistentPreRunE: func(cmd *cobra.Command, _ []string) error {
if err := client.SetCmdClientContextHandler(initClientCtx, cmd); err != nil {
return err
}
return server.InterceptConfigsPreRunHandler(cmd)
},
}
// add root sub-commands ...
2020-07-21 08:28:43 -07:00
)
```
The `SetCmdClientContextHandler` call reads persistent flags via `ReadPersistentCommandFlags`
which creates a `client.Context` and sets that on the root command's `Context`.
The `InterceptConfigsPreRunHandler` call creates a viper literal, default `server.Context`,
and a logger and sets that on the root command's `Context`. The `server.Context`
will be modified and saved to disk via the internal `interceptConfigs` call, which
either reads or creates a Tendermint configuration based on the home path provided.
In addition, `interceptConfigs` also reads and loads the application configuration,
`app.toml`, and binds that to the `server.Context` viper literal. This is vital
so the application can get access to not only the CLI flags, but also to the
application configuration values provided by this file.
## `StartCmd`
The `StartCmd` accepts an `AppCreator` function which returns an `Application`.
The `AppCreator` is responsible for constructing the application based on the
options provided to it via `AppOptions`. The `AppOptions` interface type defines
a single method, `Get() interface{}`, and is implemented as a [viper](https://github.com/spf13/viper)
literal that exists in the `server.Context`. All the possible options an application
may use and provide to the construction process are defined by the `StartCmd`
and by the application's config file, `app.toml`.
The application can either be started in-process or as an external process. The
former creates a Tendermint service and the latter creates a Tendermint Node.
Under the hood, `StartCmd` will call `GetServerContextFromCmd`, which provides
the command access to a `server.Context`. This context provides access to the
viper literal, the Tendermint config and logger. This allows flags to be bound
the viper literal and passed to the application construction.
Example:
```go
func newApp(logger log.Logger, db dbm.DB, traceStore io.Writer, appOpts server.AppOptions) server.Application {
var cache sdk.MultiStorePersistentCache
if cast.ToBool(appOpts.Get(server.FlagInterBlockCache)) {
cache = store.NewCommitKVStoreCacheManager()
}
skipUpgradeHeights := make(map[int64]bool)
for _, h := range cast.ToIntSlice(appOpts.Get(server.FlagUnsafeSkipUpgrades)) {
skipUpgradeHeights[int64(h)] = true
}
pruningOpts, err := server.GetPruningOptionsFromFlags(appOpts)
if err != nil {
panic(err)
}
return simapp.NewSimApp(
logger, db, traceStore, true, skipUpgradeHeights,
cast.ToString(appOpts.Get(flags.FlagHome)),
cast.ToUint(appOpts.Get(server.FlagInvCheckPeriod)),
baseapp.SetPruning(pruningOpts),
baseapp.SetMinGasPrices(cast.ToString(appOpts.Get(server.FlagMinGasPrices))),
baseapp.SetHaltHeight(cast.ToUint64(appOpts.Get(server.FlagHaltHeight))),
baseapp.SetHaltTime(cast.ToUint64(appOpts.Get(server.FlagHaltTime))),
baseapp.SetInterBlockCache(cache),
baseapp.SetTrace(cast.ToBool(appOpts.Get(server.FlagTrace))),
)
}
```
Note, some of the options provided are exposed via CLI flags in the start command
and some are also allowed to be set in the application's `app.toml`. It is recommend
to use the `cast` package for type safety guarantees and due to the limitations of
CLI flag types.