feat: Non-zero Default Fees (#9371)
<!-- < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < ☺ v ✰ Thanks for creating a PR! ✰ v Before smashing the submit button please review the checkboxes. v If a checkbox is n/a - please still include it but + a little note why ☺ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > --> ## Description <!-- Add a description of the changes that this PR introduces and the files that are the most critical to review. --> closes: #9106 --- Before we can merge this PR, please make sure that all the following items have been checked off. If any of the checklist items are not applicable, please leave them but write a little note why. - [x] Targeted PR against correct branch (see [CONTRIBUTING.md](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#pr-targeting)) - [ ] Linked to Github issue with discussion and accepted design OR link to spec that describes this work. - [ ] Code follows the [module structure standards](https://github.com/cosmos/cosmos-sdk/blob/master/docs/building-modules/structure.md). - [ ] Wrote unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#testing) - [ ] Updated relevant documentation (`docs/`) or specification (`x/<module>/spec/`) - [ ] Added relevant `godoc` [comments](https://blog.golang.org/godoc-documenting-go-code). - [ ] Added a relevant changelog entry to the `Unreleased` section in `CHANGELOG.md` - [ ] Re-reviewed `Files changed` in the Github PR explorer - [ ] Review `Codecov Report` in the comment section below once CI passes
This commit is contained in:
parent
bb61e2890f
commit
3fd376bd56
|
@ -42,6 +42,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
|
|||
* [\#9205](https://github.com/cosmos/cosmos-sdk/pull/9205) Improve readability in `abci` handleQueryP2P
|
||||
* [\#9314](https://github.com/cosmos/cosmos-sdk/pull/9314) Update Rosetta SDK to upstream's latest release.
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* [\#8077](https://github.com/cosmos/cosmos-sdk/pull/8077) Added support for grpc-web, enabling browsers to communicate with a chain's gRPC server
|
||||
|
@ -127,6 +128,12 @@ Ref: https://keepachangelog.com/en/1.0.0/
|
|||
* (store) [\#8790](https://github.com/cosmos/cosmos-sdk/pull/8790) Reduce gas costs by 10x for transient store operations.
|
||||
* (x/bank) [\#9051](https://github.com/cosmos/cosmos-sdk/pull/9051) Supply value is stored as `sdk.Int` rather than `string`.
|
||||
|
||||
|
||||
### CLI Breaking Changes
|
||||
|
||||
* [\#9371](https://github.com/cosmos/cosmos-sdk/pull/9371) Non-zero default fees/Server will error if there's an empty value for min-gas-price in app.toml
|
||||
|
||||
|
||||
### Improvements
|
||||
|
||||
* (baseapp) [\#9578](https://github.com/cosmos/cosmos-sdk/pull/9578) Return `Baseapp`'s `trace` value for logging error stack traces.
|
||||
|
|
Binary file not shown.
|
@ -64,10 +64,14 @@ Next is an example `rootCmd` function from the `simapp` application. It instanti
|
|||
|
||||
`rootCmd` has a function called `initAppConfig()` which is useful for setting the application's custom configs.
|
||||
By default app uses Tendermint app config template from SDK, which can be over-written via `initAppConfig()`.
|
||||
Here's an example code to override default `appConfig` and `app.toml` template.
|
||||
Here's an example code to override default `app.toml` template.
|
||||
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/4eea4cafd3b8b1c2cd493886db524500c9dd745c/simapp/simd/cmd/root.go#L84-L117
|
||||
|
||||
The `initAppConfig()` also allows overriding the default SDK's [server config](https://github.com/cosmos/cosmos-sdk/blob/4eea4cafd3b8b1c2cd493886db524500c9dd745c/server/config/config.go#L199). One example is the `min-gas-prices` config, which defines the minimum gas prices a validator is willing to accept for processing a transaction. By default, the SDK sets this parameter to `""` (empty string), which forces all validators to tweak their own `app.toml` and set a non-empty value, or else the node will halt on startup. This might not be the best UX for validators, so the chain developer can set a default `app.toml` value for validators inside this `initAppConfig()` function.
|
||||
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/aa9b055ddb46aacd4737335a92d0b8a82d577341/simapp/simd/cmd/root.go#L101-L116
|
||||
|
||||
The root-level `status` and `keys` subcommands are common across most applications and do not interact with application state. The bulk of an application's functionality - what users can actually _do_ with it - is enabled by its `tx` and `query` commands.
|
||||
|
||||
### Transaction Commands
|
||||
|
|
|
@ -71,6 +71,24 @@ For more information on `gentx`, use the following command:
|
|||
simd gentx --help
|
||||
```
|
||||
|
||||
## Configuring the Node Using `app.toml` and `config.toml`
|
||||
|
||||
The Cosmos SDK automatically generates two configuration files inside `~/.simapp/config`:
|
||||
|
||||
- `config.toml`: used to configure the Tendermint, learn more on [Tendermint's documentation](https://docs.tendermint.com/master/nodes/configuration.html),
|
||||
- `app.toml`: generated by the Cosmos SDK, and used to configure your app, such as state pruning strategies, telemetry, gRPC and REST servers configuration, state sync...
|
||||
|
||||
Both files are heavily commented, please refer to them directly to tweak your node.
|
||||
|
||||
One example config to tweak is the `minimum-gas-prices` field inside `app.toml`, which defines the minimum gas prices the validator node is willing to accept for processing a transaction. Depending on the chain, it might be an empty string or not. If it's empty, make sure to edit the field with some value, for example `10token`, or else the node will halt on startup. For the purpose of this tutorial, let's set the minimum gas price to 0:
|
||||
|
||||
```toml
|
||||
# The minimum gas prices a validator is willing to accept for processing a
|
||||
# transaction. A transaction's fees must meet the minimum of any denomination
|
||||
# specified in this config (e.g. 0.25token1;0.0001token2).
|
||||
minimum-gas-prices = "0stake"
|
||||
```
|
||||
|
||||
## Run a Localnet
|
||||
|
||||
Now that everything is set up, you can finally start your node:
|
||||
|
@ -85,12 +103,6 @@ The previous command allow you to run a single node. This is enough for the next
|
|||
|
||||
The naive way would be to run the same commands again in separate terminal windows. This is possible, however in the SDK, we leverage the power of [Docker Compose](https://docs.docker.com/compose/) to run a localnet. If you need inspiration on how to set up your own localnet with Docker Compose, you can have a look at the SDK's [`docker-compose.yml`](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/docker-compose.yml).
|
||||
|
||||
## Configuring the Node Using `app.toml`
|
||||
|
||||
The Cosmos SDK automatically generates an `app.toml` file inside `~/.simapp/config`. This file is used to configure your app, such as state pruning strategies, telemetry, gRPC and REST servers configuration, state sync... The file itself is heavily commented, please refer to it directly to tweak your node.
|
||||
|
||||
Make sure to restart your node after modifying `app.toml`.
|
||||
|
||||
## Next {hide}
|
||||
|
||||
Read about the [Interacting with your Node](./interact-node.md) {hide}
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
storetypes "github.com/cosmos/cosmos-sdk/store/types"
|
||||
"github.com/cosmos/cosmos-sdk/telemetry"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -310,3 +311,12 @@ func GetConfig(v *viper.Viper) Config {
|
|||
},
|
||||
}
|
||||
}
|
||||
|
||||
// ValidateBasic returns an error if min-gas-prices field is empty in BaseConfig. Otherwise, it returns nil.
|
||||
func (c Config) ValidateBasic() error {
|
||||
if c.BaseConfig.MinGasPrices == "" {
|
||||
return sdkerrors.ErrAppConfig.Wrap("set min gas price in app.toml or flag or env variable")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -245,6 +245,11 @@ func startInProcess(ctx *Context, clientCtx client.Context, appCreator types.App
|
|||
return err
|
||||
}
|
||||
|
||||
config := config.GetConfig(ctx.Viper)
|
||||
if err := config.ValidateBasic(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
app := appCreator(ctx.Logger, db, traceWriter, ctx.Viper)
|
||||
|
||||
nodeKey, err := p2p.LoadOrGenNodeKey(cfg.NodeKeyFile())
|
||||
|
@ -273,8 +278,6 @@ func startInProcess(ctx *Context, clientCtx client.Context, appCreator types.App
|
|||
}
|
||||
ctx.Logger.Debug("initialization: tmNode started")
|
||||
|
||||
config := config.GetConfig(ctx.Viper)
|
||||
|
||||
// Add the tx service to the gRPC router. We only need to register this
|
||||
// service if API or gRPC is enabled, and avoid doing so in the general
|
||||
// case, because it spawns a new local tendermint RPC client.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package server
|
||||
package server_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
@ -11,35 +11,42 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
"github.com/cosmos/cosmos-sdk/server"
|
||||
"github.com/cosmos/cosmos-sdk/server/config"
|
||||
"github.com/cosmos/cosmos-sdk/simapp"
|
||||
genutilcli "github.com/cosmos/cosmos-sdk/x/genutil/client/cli"
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
)
|
||||
|
||||
var CancelledInPreRun = errors.New("Canelled in prerun")
|
||||
var cancelledInPreRun = errors.New("Cancelled in prerun")
|
||||
|
||||
// Used in each test to run the function under test via Cobra
|
||||
// but to always halt the command
|
||||
func preRunETestImpl(cmd *cobra.Command, args []string) error {
|
||||
err := InterceptConfigsPreRunHandler(cmd, "", nil)
|
||||
err := server.InterceptConfigsPreRunHandler(cmd, "", nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return CancelledInPreRun
|
||||
return cancelledInPreRun
|
||||
}
|
||||
|
||||
func TestInterceptConfigsPreRunHandlerCreatesConfigFilesWhenMissing(t *testing.T) {
|
||||
tempDir := t.TempDir()
|
||||
cmd := StartCmd(nil, "/foobar")
|
||||
cmd := server.StartCmd(nil, "/foobar")
|
||||
if err := cmd.Flags().Set(flags.FlagHome, tempDir); err != nil {
|
||||
t.Fatalf("Could not set home flag [%T] %v", err, err)
|
||||
}
|
||||
|
||||
cmd.PreRunE = preRunETestImpl
|
||||
|
||||
serverCtx := &Context{}
|
||||
ctx := context.WithValue(context.Background(), ServerContextKey, serverCtx)
|
||||
if err := cmd.ExecuteContext(ctx); err != CancelledInPreRun {
|
||||
serverCtx := &server.Context{}
|
||||
ctx := context.WithValue(context.Background(), server.ServerContextKey, serverCtx)
|
||||
if err := cmd.ExecuteContext(ctx); err != cancelledInPreRun {
|
||||
t.Fatalf("function failed with [%T] %v", err, err)
|
||||
}
|
||||
|
||||
|
@ -106,17 +113,17 @@ func TestInterceptConfigsPreRunHandlerReadsConfigToml(t *testing.T) {
|
|||
t.Fatalf("Failed closing config.toml: %v", err)
|
||||
}
|
||||
|
||||
cmd := StartCmd(nil, "/foobar")
|
||||
cmd := server.StartCmd(nil, "/foobar")
|
||||
if err := cmd.Flags().Set(flags.FlagHome, tempDir); err != nil {
|
||||
t.Fatalf("Could not set home flag [%T] %v", err, err)
|
||||
}
|
||||
|
||||
cmd.PreRunE = preRunETestImpl
|
||||
|
||||
serverCtx := &Context{}
|
||||
ctx := context.WithValue(context.Background(), ServerContextKey, serverCtx)
|
||||
serverCtx := &server.Context{}
|
||||
ctx := context.WithValue(context.Background(), server.ServerContextKey, serverCtx)
|
||||
|
||||
if err := cmd.ExecuteContext(ctx); err != CancelledInPreRun {
|
||||
if err := cmd.ExecuteContext(ctx); err != cancelledInPreRun {
|
||||
t.Fatalf("function failed with [%T] %v", err, err)
|
||||
}
|
||||
|
||||
|
@ -146,14 +153,14 @@ func TestInterceptConfigsPreRunHandlerReadsAppToml(t *testing.T) {
|
|||
if err := writer.Close(); err != nil {
|
||||
t.Fatalf("Failed closing app.toml: %v", err)
|
||||
}
|
||||
cmd := StartCmd(nil, tempDir)
|
||||
cmd := server.StartCmd(nil, tempDir)
|
||||
|
||||
cmd.PreRunE = preRunETestImpl
|
||||
|
||||
serverCtx := &Context{}
|
||||
ctx := context.WithValue(context.Background(), ServerContextKey, serverCtx)
|
||||
serverCtx := &server.Context{}
|
||||
ctx := context.WithValue(context.Background(), server.ServerContextKey, serverCtx)
|
||||
|
||||
if err := cmd.ExecuteContext(ctx); err != CancelledInPreRun {
|
||||
if err := cmd.ExecuteContext(ctx); err != cancelledInPreRun {
|
||||
t.Fatalf("function failed with [%T] %v", err, err)
|
||||
}
|
||||
|
||||
|
@ -165,7 +172,7 @@ func TestInterceptConfigsPreRunHandlerReadsAppToml(t *testing.T) {
|
|||
func TestInterceptConfigsPreRunHandlerReadsFlags(t *testing.T) {
|
||||
const testAddr = "tcp://127.1.2.3:12345"
|
||||
tempDir := t.TempDir()
|
||||
cmd := StartCmd(nil, "/foobar")
|
||||
cmd := server.StartCmd(nil, "/foobar")
|
||||
|
||||
if err := cmd.Flags().Set(flags.FlagHome, tempDir); err != nil {
|
||||
t.Fatalf("Could not set home flag [%T] %v", err, err)
|
||||
|
@ -178,10 +185,10 @@ func TestInterceptConfigsPreRunHandlerReadsFlags(t *testing.T) {
|
|||
|
||||
cmd.PreRunE = preRunETestImpl
|
||||
|
||||
serverCtx := &Context{}
|
||||
ctx := context.WithValue(context.Background(), ServerContextKey, serverCtx)
|
||||
serverCtx := &server.Context{}
|
||||
ctx := context.WithValue(context.Background(), server.ServerContextKey, serverCtx)
|
||||
|
||||
if err := cmd.ExecuteContext(ctx); err != CancelledInPreRun {
|
||||
if err := cmd.ExecuteContext(ctx); err != cancelledInPreRun {
|
||||
t.Fatalf("function failed with [%T] %v", err, err)
|
||||
}
|
||||
|
||||
|
@ -193,7 +200,7 @@ func TestInterceptConfigsPreRunHandlerReadsFlags(t *testing.T) {
|
|||
func TestInterceptConfigsPreRunHandlerReadsEnvVars(t *testing.T) {
|
||||
const testAddr = "tcp://127.1.2.3:12345"
|
||||
tempDir := t.TempDir()
|
||||
cmd := StartCmd(nil, "/foobar")
|
||||
cmd := server.StartCmd(nil, "/foobar")
|
||||
if err := cmd.Flags().Set(flags.FlagHome, tempDir); err != nil {
|
||||
t.Fatalf("Could not set home flag [%T] %v", err, err)
|
||||
}
|
||||
|
@ -213,10 +220,10 @@ func TestInterceptConfigsPreRunHandlerReadsEnvVars(t *testing.T) {
|
|||
|
||||
cmd.PreRunE = preRunETestImpl
|
||||
|
||||
serverCtx := &Context{}
|
||||
ctx := context.WithValue(context.Background(), ServerContextKey, serverCtx)
|
||||
serverCtx := &server.Context{}
|
||||
ctx := context.WithValue(context.Background(), server.ServerContextKey, serverCtx)
|
||||
|
||||
if err := cmd.ExecuteContext(ctx); err != CancelledInPreRun {
|
||||
if err := cmd.ExecuteContext(ctx); err != cancelledInPreRun {
|
||||
t.Fatalf("function failed with [%T] %v", err, err)
|
||||
}
|
||||
|
||||
|
@ -279,7 +286,7 @@ func newPrecedenceCommon(t *testing.T) precedenceCommon {
|
|||
})
|
||||
|
||||
// Set up the command object that is used in this test
|
||||
retval.cmd = StartCmd(nil, tempDir)
|
||||
retval.cmd = server.StartCmd(nil, tempDir)
|
||||
retval.cmd.PreRunE = preRunETestImpl
|
||||
|
||||
return retval
|
||||
|
@ -317,10 +324,10 @@ func TestInterceptConfigsPreRunHandlerPrecedenceFlag(t *testing.T) {
|
|||
testCommon := newPrecedenceCommon(t)
|
||||
testCommon.setAll(t, &TestAddrExpected, &TestAddrNotExpected, &TestAddrNotExpected)
|
||||
|
||||
serverCtx := &Context{}
|
||||
ctx := context.WithValue(context.Background(), ServerContextKey, serverCtx)
|
||||
serverCtx := &server.Context{}
|
||||
ctx := context.WithValue(context.Background(), server.ServerContextKey, serverCtx)
|
||||
|
||||
if err := testCommon.cmd.ExecuteContext(ctx); err != CancelledInPreRun {
|
||||
if err := testCommon.cmd.ExecuteContext(ctx); err != cancelledInPreRun {
|
||||
t.Fatalf("function failed with [%T] %v", err, err)
|
||||
}
|
||||
|
||||
|
@ -333,10 +340,10 @@ func TestInterceptConfigsPreRunHandlerPrecedenceEnvVar(t *testing.T) {
|
|||
testCommon := newPrecedenceCommon(t)
|
||||
testCommon.setAll(t, nil, &TestAddrExpected, &TestAddrNotExpected)
|
||||
|
||||
serverCtx := &Context{}
|
||||
ctx := context.WithValue(context.Background(), ServerContextKey, serverCtx)
|
||||
serverCtx := &server.Context{}
|
||||
ctx := context.WithValue(context.Background(), server.ServerContextKey, serverCtx)
|
||||
|
||||
if err := testCommon.cmd.ExecuteContext(ctx); err != CancelledInPreRun {
|
||||
if err := testCommon.cmd.ExecuteContext(ctx); err != cancelledInPreRun {
|
||||
t.Fatalf("function failed with [%T] %v", err, err)
|
||||
}
|
||||
|
||||
|
@ -349,10 +356,10 @@ func TestInterceptConfigsPreRunHandlerPrecedenceConfigFile(t *testing.T) {
|
|||
testCommon := newPrecedenceCommon(t)
|
||||
testCommon.setAll(t, nil, nil, &TestAddrExpected)
|
||||
|
||||
serverCtx := &Context{}
|
||||
ctx := context.WithValue(context.Background(), ServerContextKey, serverCtx)
|
||||
serverCtx := &server.Context{}
|
||||
ctx := context.WithValue(context.Background(), server.ServerContextKey, serverCtx)
|
||||
|
||||
if err := testCommon.cmd.ExecuteContext(ctx); err != CancelledInPreRun {
|
||||
if err := testCommon.cmd.ExecuteContext(ctx); err != cancelledInPreRun {
|
||||
t.Fatalf("function failed with [%T] %v", err, err)
|
||||
}
|
||||
|
||||
|
@ -365,10 +372,10 @@ func TestInterceptConfigsPreRunHandlerPrecedenceConfigDefault(t *testing.T) {
|
|||
testCommon := newPrecedenceCommon(t)
|
||||
// Do not set anything
|
||||
|
||||
serverCtx := &Context{}
|
||||
ctx := context.WithValue(context.Background(), ServerContextKey, serverCtx)
|
||||
serverCtx := &server.Context{}
|
||||
ctx := context.WithValue(context.Background(), server.ServerContextKey, serverCtx)
|
||||
|
||||
if err := testCommon.cmd.ExecuteContext(ctx); err != CancelledInPreRun {
|
||||
if err := testCommon.cmd.ExecuteContext(ctx); err != cancelledInPreRun {
|
||||
t.Fatalf("function failed with [%T] %v", err, err)
|
||||
}
|
||||
|
||||
|
@ -386,16 +393,47 @@ func TestInterceptConfigsWithBadPermissions(t *testing.T) {
|
|||
if err := os.Mkdir(subDir, 0600); err != nil {
|
||||
t.Fatalf("Failed to create sub directory: %v", err)
|
||||
}
|
||||
cmd := StartCmd(nil, "/foobar")
|
||||
cmd := server.StartCmd(nil, "/foobar")
|
||||
if err := cmd.Flags().Set(flags.FlagHome, subDir); err != nil {
|
||||
t.Fatalf("Could not set home flag [%T] %v", err, err)
|
||||
}
|
||||
|
||||
cmd.PreRunE = preRunETestImpl
|
||||
|
||||
serverCtx := &Context{}
|
||||
ctx := context.WithValue(context.Background(), ServerContextKey, serverCtx)
|
||||
serverCtx := &server.Context{}
|
||||
ctx := context.WithValue(context.Background(), server.ServerContextKey, serverCtx)
|
||||
if err := cmd.ExecuteContext(ctx); !os.IsPermission(err) {
|
||||
t.Fatalf("Failed to catch permissions error, got: [%T] %v", err, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEmptyMinGasPrices(t *testing.T) {
|
||||
tempDir := t.TempDir()
|
||||
err := os.Mkdir(filepath.Join(tempDir, "config"), os.ModePerm)
|
||||
require.NoError(t, err)
|
||||
encCfg := simapp.MakeTestEncodingConfig()
|
||||
|
||||
// Run InitCmd to create necessary config files.
|
||||
clientCtx := client.Context{}.WithHomeDir(tempDir).WithJSONCodec(encCfg.Marshaler)
|
||||
serverCtx := server.NewDefaultContext()
|
||||
ctx := context.WithValue(context.Background(), server.ServerContextKey, serverCtx)
|
||||
ctx = context.WithValue(ctx, client.ClientContextKey, &clientCtx)
|
||||
cmd := genutilcli.InitCmd(simapp.ModuleBasics, tempDir)
|
||||
cmd.SetArgs([]string{"appnode-test"})
|
||||
err = cmd.ExecuteContext(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Modify app.toml.
|
||||
appCfgTempFilePath := filepath.Join(tempDir, "config", "app.toml")
|
||||
appConf := config.DefaultConfig()
|
||||
appConf.BaseConfig.MinGasPrices = ""
|
||||
config.WriteConfigFile(appCfgTempFilePath, appConf)
|
||||
|
||||
// Run StartCmd.
|
||||
cmd = server.StartCmd(nil, tempDir)
|
||||
cmd.PreRunE = func(cmd *cobra.Command, _ []string) error {
|
||||
return server.InterceptConfigsPreRunHandler(cmd, "", nil)
|
||||
}
|
||||
err = cmd.ExecuteContext(ctx)
|
||||
require.Errorf(t, err, sdkerrors.ErrAppConfig.Error())
|
||||
}
|
||||
|
|
|
@ -98,8 +98,25 @@ func initAppConfig() (string, interface{}) {
|
|||
WASM WASMConfig `mapstructure:"wasm"`
|
||||
}
|
||||
|
||||
// Optionally allow the chain developer to overwrite the SDK's default
|
||||
// server config.
|
||||
srvCfg := serverconfig.DefaultConfig()
|
||||
// The SDK's default minimum gas price is set to "" (empty value) inside
|
||||
// app.toml. If left empty by validators, the node will halt on startup.
|
||||
// However, the chain developer can set a default app.toml value for their
|
||||
// validators here.
|
||||
//
|
||||
// In summary:
|
||||
// - if you leave srvCfg.MinGasPrices = "", all validators MUST tweak their
|
||||
// own app.toml config,
|
||||
// - if you set srvCfg.MinGasPrices non-empty, validators CAN tweak their
|
||||
// own app.toml to override, or use this default value.
|
||||
//
|
||||
// In simapp, we set the min gas prices to 0.
|
||||
srvCfg.MinGasPrices = "0stake"
|
||||
|
||||
customAppConfig := CustomAppConfig{
|
||||
Config: *serverconfig.DefaultConfig(),
|
||||
Config: *srvCfg,
|
||||
WASM: WASMConfig{
|
||||
LruSize: 1,
|
||||
QueryGasLimit: 300000,
|
||||
|
@ -207,7 +224,7 @@ type appCreator struct {
|
|||
encCfg params.EncodingConfig
|
||||
}
|
||||
|
||||
// newApp is an AppCreator
|
||||
// newApp is an appCreator
|
||||
func (a appCreator) newApp(logger log.Logger, db dbm.DB, traceStore io.Writer, appOpts servertypes.AppOptions) servertypes.Application {
|
||||
var cache sdk.MultiStorePersistentCache
|
||||
|
||||
|
|
|
@ -27,6 +27,10 @@ func startInProcess(cfg Config, val *Validator) error {
|
|||
tmCfg := val.Ctx.Config
|
||||
tmCfg.Instrumentation.Prometheus = false
|
||||
|
||||
if err := val.AppConfig.ValidateBasic(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
nodeKey, err := p2p.LoadOrGenNodeKey(tmCfg.NodeKeyFile())
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -144,6 +144,9 @@ var (
|
|||
// ErrPanic is only set when we recover from a panic, so we know to
|
||||
// redact potentially sensitive system info
|
||||
ErrPanic = Register(UndefinedCodespace, 111222, "panic")
|
||||
|
||||
// ErrAppConfig defines an error occurred if min-gas-prices field in BaseConfig is empty.
|
||||
ErrAppConfig = Register(RootCodespace, 40, "error in app.toml")
|
||||
)
|
||||
|
||||
// Register returns an error instance that should be used as the base for
|
||||
|
|
Loading…
Reference in New Issue