Server/simd: Viper Removal (#6599)

* init commit

* remove viper from tm cmds

* updates

* Undo x/bank/client/cli/tx.go

* Fix unit tests

* lint++

* rename var

* Fix genutil test

* fix test

* prefer cmd.Flags() over direct viper usage

* update

* fix ABCI error tests

* fix integration tests

* Add viper to context

* fix build

* fix unit test

* Implement and use AppOptions

* Revert Redact godoc

Co-authored-by: Alessio Treglia <alessio@tendermint.com>
This commit is contained in:
Alexander Bezobchuk 2020-07-05 12:56:17 -04:00 committed by GitHub
parent b832e103b1
commit 9ebda4edb9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 319 additions and 357 deletions

View File

@ -172,7 +172,7 @@ func (app *BaseApp) CheckTx(req abci.RequestCheckTx) abci.ResponseCheckTx {
tx, err := app.txDecoder(req.Tx)
if err != nil {
return sdkerrors.ResponseCheckTx(err, 0, 0)
return sdkerrors.ResponseCheckTx(err, 0, 0, app.trace)
}
var mode runTxMode
@ -190,7 +190,7 @@ func (app *BaseApp) CheckTx(req abci.RequestCheckTx) abci.ResponseCheckTx {
gInfo, result, err := app.runTx(mode, req.Tx, tx)
if err != nil {
return sdkerrors.ResponseCheckTx(err, gInfo.GasWanted, gInfo.GasUsed)
return sdkerrors.ResponseCheckTx(err, gInfo.GasWanted, gInfo.GasUsed, app.trace)
}
return abci.ResponseCheckTx{
@ -212,7 +212,7 @@ func (app *BaseApp) DeliverTx(req abci.RequestDeliverTx) abci.ResponseDeliverTx
tx, err := app.txDecoder(req.Tx)
if err != nil {
return sdkerrors.ResponseDeliverTx(err, 0, 0)
return sdkerrors.ResponseDeliverTx(err, 0, 0, app.trace)
}
gInfo := sdk.GasInfo{}
@ -228,7 +228,7 @@ func (app *BaseApp) DeliverTx(req abci.RequestDeliverTx) abci.ResponseDeliverTx
gInfo, result, err := app.runTx(runTxModeDeliver, req.Tx, tx)
if err != nil {
resultStr = "failed"
return sdkerrors.ResponseDeliverTx(err, gInfo.GasWanted, gInfo.GasUsed)
return sdkerrors.ResponseDeliverTx(err, gInfo.GasWanted, gInfo.GasUsed, app.trace)
}
return abci.ResponseDeliverTx{

View File

@ -95,6 +95,9 @@ type BaseApp struct { // nolint: maligned
// recovery handler for app.runTx method
runTxRecoveryMiddleware recoveryMiddleware
// trace set will return full stack traces for errors in ABCI Log field
trace bool
}
// NewBaseApp returns a reference to an initialized BaseApp. It accepts a
@ -276,6 +279,10 @@ func (app *BaseApp) setInterBlockCache(cache sdk.MultiStorePersistentCache) {
app.interBlockCache = cache
}
func (app *BaseApp) setTrace(trace bool) {
app.trace = trace
}
// Router returns the router of the BaseApp.
func (app *BaseApp) Router() sdk.Router {
if app.sealed {

View File

@ -38,6 +38,11 @@ func SetHaltTime(haltTime uint64) func(*BaseApp) {
return func(bap *BaseApp) { bap.setHaltTime(haltTime) }
}
// SetTrace will turn on or off trace flag
func SetTrace(trace bool) func(*BaseApp) {
return func(app *BaseApp) { app.setTrace(trace) }
}
// SetInterBlockCache provides a BaseApp option function that sets the
// inter-block cache.
func SetInterBlockCache(cache sdk.MultiStorePersistentCache) func(*BaseApp) {

1
go.mod
View File

@ -28,6 +28,7 @@ require (
github.com/rakyll/statik v0.1.7
github.com/regen-network/cosmos-proto v0.3.0
github.com/spf13/afero v1.2.2 // indirect
github.com/spf13/cast v1.3.0
github.com/spf13/cobra v1.0.0
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.5

View File

@ -138,8 +138,8 @@ func DefaultConfig() *Config {
}
// GetConfig returns a fully parsed Config object.
func GetConfig() Config {
globalLabelsRaw := viper.Get("telemetry.global-labels").([]interface{})
func GetConfig(v *viper.Viper) Config {
globalLabelsRaw := v.Get("telemetry.global-labels").([]interface{})
globalLabels := make([][]string, 0, len(globalLabelsRaw))
for _, glr := range globalLabelsRaw {
labelsRaw := glr.([]interface{})
@ -150,32 +150,32 @@ func GetConfig() Config {
return Config{
BaseConfig: BaseConfig{
MinGasPrices: viper.GetString("minimum-gas-prices"),
InterBlockCache: viper.GetBool("inter-block-cache"),
Pruning: viper.GetString("pruning"),
PruningKeepRecent: viper.GetString("pruning-keep-recent"),
PruningKeepEvery: viper.GetString("pruning-keep-every"),
PruningInterval: viper.GetString("pruning-interval"),
HaltHeight: viper.GetUint64("halt-height"),
HaltTime: viper.GetUint64("halt-time"),
MinGasPrices: v.GetString("minimum-gas-prices"),
InterBlockCache: v.GetBool("inter-block-cache"),
Pruning: v.GetString("pruning"),
PruningKeepRecent: v.GetString("pruning-keep-recent"),
PruningKeepEvery: v.GetString("pruning-keep-every"),
PruningInterval: v.GetString("pruning-interval"),
HaltHeight: v.GetUint64("halt-height"),
HaltTime: v.GetUint64("halt-time"),
},
Telemetry: telemetry.Config{
ServiceName: viper.GetString("telemetry.service-name"),
Enabled: viper.GetBool("telemetry.enabled"),
EnableHostname: viper.GetBool("telemetry.enable-hostname"),
EnableHostnameLabel: viper.GetBool("telemetry.enable-hostname-label"),
EnableServiceLabel: viper.GetBool("telemetry.enable-service-label"),
PrometheusRetentionTime: viper.GetInt64("telemetry.prometheus-retention-time"),
ServiceName: v.GetString("telemetry.service-name"),
Enabled: v.GetBool("telemetry.enabled"),
EnableHostname: v.GetBool("telemetry.enable-hostname"),
EnableHostnameLabel: v.GetBool("telemetry.enable-hostname-label"),
EnableServiceLabel: v.GetBool("telemetry.enable-service-label"),
PrometheusRetentionTime: v.GetInt64("telemetry.prometheus-retention-time"),
GlobalLabels: globalLabels,
},
API: APIConfig{
Enable: viper.GetBool("api.enable"),
Address: viper.GetString("api.address"),
MaxOpenConnections: viper.GetUint("api.max-open-connections"),
RPCReadTimeout: viper.GetUint("api.rpc-read-timeout"),
RPCWriteTimeout: viper.GetUint("api.rpc-write-timeout"),
RPCMaxBodyBytes: viper.GetUint("api.rpc-max-body-bytes"),
EnableUnsafeCORS: viper.GetBool("api.enabled-unsafe-cors"),
Enable: v.GetBool("api.enable"),
Address: v.GetString("api.address"),
MaxOpenConnections: v.GetUint("api.max-open-connections"),
RPCReadTimeout: v.GetUint("api.rpc-read-timeout"),
RPCWriteTimeout: v.GetUint("api.rpc-write-timeout"),
RPCMaxBodyBytes: v.GetUint("api.rpc-max-body-bytes"),
EnableUnsafeCORS: v.GetBool("api.enabled-unsafe-cors"),
},
}
}

View File

@ -127,9 +127,9 @@ func init() {
// ParseConfig retrieves the default environment configuration for the
// application.
func ParseConfig() (*Config, error) {
func ParseConfig(v *viper.Viper) (*Config, error) {
conf := DefaultConfig()
err := viper.Unmarshal(conf)
err := v.Unmarshal(conf)
return conf, err
}

View File

@ -16,6 +16,17 @@ import (
)
type (
// AppOptions defines an interface that is passed into an application
// constructor, typically used to set BaseApp options that are either supplied
// via config file or through CLI arguments/flags. The underlying implementation
// is defined by the server package and is typically implemented via a Viper
// literal defined on the server Context. Note, casting Get calls may not yield
// the expected types and could result in type assertion errors. It is recommend
// to either use the cast package or perform manual conversion for safety.
AppOptions interface {
Get(string) interface{}
}
// Application defines an application interface that wraps abci.Application.
// The interface defines the necessary contracts to be implemented in order
// to fully bootstrap and start an application.
@ -27,7 +38,7 @@ type (
// AppCreator is a function that allows us to lazily initialize an
// application using various configurations.
AppCreator func(log.Logger, dbm.DB, io.Writer) Application
AppCreator func(log.Logger, dbm.DB, io.Writer, AppOptions) Application
// AppExporter is a function that dumps all app state to
// JSON-serializable structure and returns the current validator set.

View File

@ -8,7 +8,6 @@ import (
"os"
"github.com/spf13/cobra"
"github.com/spf13/viper"
tmtypes "github.com/tendermint/tendermint/types"
"github.com/cosmos/cosmos-sdk/client/flags"
@ -29,9 +28,9 @@ func ExportCmd(ctx *Context, cdc codec.JSONMarshaler, appExporter AppExporter) *
Short: "Export state to JSON",
RunE: func(cmd *cobra.Command, args []string) error {
config := ctx.Config
config.SetRoot(viper.GetString(flags.FlagHome))
traceWriterFile := viper.GetString(flagTraceStore)
homeDir, _ := cmd.Flags().GetString(flags.FlagHome)
config.SetRoot(homeDir)
db, err := openDB(config.RootDir)
if err != nil {
@ -52,14 +51,15 @@ func ExportCmd(ctx *Context, cdc codec.JSONMarshaler, appExporter AppExporter) *
return nil
}
traceWriterFile, _ := cmd.Flags().GetString(flagTraceStore)
traceWriter, err := openTraceWriter(traceWriterFile)
if err != nil {
return err
}
height := viper.GetInt64(flagHeight)
forZeroHeight := viper.GetBool(flagForZeroHeight)
jailWhiteList := viper.GetStringSlice(flagJailWhitelist)
height, _ := cmd.Flags().GetInt64(flagHeight)
forZeroHeight, _ := cmd.Flags().GetBool(flagForZeroHeight)
jailWhiteList, _ := cmd.Flags().GetStringSlice(flagJailWhitelist)
appState, validators, cp, err := appExporter(ctx.Logger, db, traceWriter, height, forZeroHeight, jailWhiteList)
if err != nil {
@ -98,11 +98,10 @@ func ExportCmd(ctx *Context, cdc codec.JSONMarshaler, appExporter AppExporter) *
},
}
cmd.Flags().String(flags.FlagHome, "", "The application home directory")
cmd.Flags().Int64(flagHeight, -1, "Export state from a particular height (-1 means latest height)")
cmd.Flags().Bool(flagForZeroHeight, false, "Export state to start at height zero (perform preproccessing)")
cmd.Flags().StringSlice(flagJailWhitelist, []string{}, "List of validators to not jail state export")
cmd.SetOut(cmd.OutOrStdout())
cmd.SetErr(cmd.OutOrStderr())
return cmd
}

View File

@ -3,6 +3,7 @@ package server
import (
"bytes"
"encoding/json"
"fmt"
"io"
"os"
"path"
@ -10,8 +11,6 @@ import (
"github.com/stretchr/testify/require"
"github.com/spf13/viper"
abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/libs/log"
tmtypes "github.com/tendermint/tendermint/types"
@ -62,12 +61,8 @@ func TestExportCmd_ConsensusParams(t *testing.T) {
output := &bytes.Buffer{}
cmd.SetOut(output)
viper.Set(flags.FlagHome, tempDir)
err = cmd.RunE(cmd, []string{})
if err != nil {
t.Errorf("error: %s", err)
}
cmd.SetArgs([]string{fmt.Sprintf("--%s=%s", flags.FlagHome, tempDir)})
require.NoError(t, cmd.Execute())
var exportedGenDoc tmtypes.GenesisDoc
err = app.Codec().UnmarshalJSON(output.Bytes(), &exportedGenDoc)

View File

@ -4,7 +4,7 @@ import (
"fmt"
"strings"
"github.com/spf13/viper"
"github.com/spf13/cast"
"github.com/cosmos/cosmos-sdk/store"
"github.com/cosmos/cosmos-sdk/store/types"
@ -13,8 +13,8 @@ import (
// GetPruningOptionsFromFlags parses command flags and returns the correct
// PruningOptions. If a pruning strategy is provided, that will be parsed and
// returned, otherwise, it is assumed custom pruning options are provided.
func GetPruningOptionsFromFlags() (types.PruningOptions, error) {
strategy := strings.ToLower(viper.GetString(FlagPruning))
func GetPruningOptionsFromFlags(appOpts AppOptions) (types.PruningOptions, error) {
strategy := strings.ToLower(cast.ToString(appOpts.Get(FlagPruning)))
switch strategy {
case types.PruningOptionDefault, types.PruningOptionNothing, types.PruningOptionEverything:
@ -22,8 +22,9 @@ func GetPruningOptionsFromFlags() (types.PruningOptions, error) {
case types.PruningOptionCustom:
opts := types.NewPruningOptions(
viper.GetUint64(FlagPruningKeepRecent),
viper.GetUint64(FlagPruningKeepEvery), viper.GetUint64(FlagPruningInterval),
cast.ToUint64(appOpts.Get(FlagPruningKeepRecent)),
cast.ToUint64(appOpts.Get(FlagPruningKeepEvery)),
cast.ToUint64(appOpts.Get(FlagPruningInterval)),
)
if err := opts.Validate(); err != nil {

View File

@ -12,24 +12,29 @@ import (
func TestGetPruningOptionsFromFlags(t *testing.T) {
tests := []struct {
name string
initParams func()
initParams func() *viper.Viper
expectedOptions types.PruningOptions
wantErr bool
}{
{
name: FlagPruning,
initParams: func() {
viper.Set(FlagPruning, types.PruningOptionNothing)
initParams: func() *viper.Viper {
v := viper.New()
v.Set(FlagPruning, types.PruningOptionNothing)
return v
},
expectedOptions: types.PruneNothing,
},
{
name: "custom pruning options",
initParams: func() {
viper.Set(FlagPruning, types.PruningOptionCustom)
viper.Set(FlagPruningKeepRecent, 1234)
viper.Set(FlagPruningKeepEvery, 4321)
viper.Set(FlagPruningInterval, 10)
initParams: func() *viper.Viper {
v := viper.New()
v.Set(FlagPruning, types.PruningOptionCustom)
v.Set(FlagPruningKeepRecent, 1234)
v.Set(FlagPruningKeepEvery, 4321)
v.Set(FlagPruningInterval, 10)
return v
},
expectedOptions: types.PruningOptions{
KeepRecent: 1234,
@ -38,8 +43,12 @@ func TestGetPruningOptionsFromFlags(t *testing.T) {
},
},
{
name: types.PruningOptionDefault,
initParams: func() {},
name: types.PruningOptionDefault,
initParams: func() *viper.Viper {
v := viper.New()
v.Set(FlagPruning, types.PruningOptionDefault)
return v
},
expectedOptions: types.PruneDefault,
},
}
@ -50,9 +59,9 @@ func TestGetPruningOptionsFromFlags(t *testing.T) {
t.Run(tt.name, func(j *testing.T) {
viper.Reset()
viper.SetDefault(FlagPruning, types.PruningOptionDefault)
tt.initParams()
v := tt.initParams()
opts, err := GetPruningOptionsFromFlags()
opts, err := GetPruningOptionsFromFlags(v)
if tt.wantErr {
require.Error(t, err)
return

View File

@ -9,7 +9,6 @@ import (
"time"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/tendermint/tendermint/abci/server"
tcmd "github.com/tendermint/tendermint/cmd/tendermint/commands"
tmos "github.com/tendermint/tendermint/libs/os"
@ -20,6 +19,7 @@ import (
"github.com/tendermint/tendermint/rpc/client/local"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/server/api"
"github.com/cosmos/cosmos-sdk/server/config"
@ -37,6 +37,8 @@ const (
FlagHaltTime = "halt-time"
FlagInterBlockCache = "inter-block-cache"
FlagUnsafeSkipUpgrades = "unsafe-skip-upgrades"
FlagTrace = "trace"
FlagInvCheckPeriod = "inv-check-period"
FlagPruning = "pruning"
FlagPruningKeepRecent = "pruning-keep-recent"
@ -73,11 +75,12 @@ For profiling and benchmarking purposes, CPU profiling can be enabled via the '-
which accepts a path for the resulting pprof file.
`,
PreRunE: func(cmd *cobra.Command, args []string) error {
_, err := GetPruningOptionsFromFlags()
_, err := GetPruningOptionsFromFlags(ctx.Viper)
return err
},
RunE: func(cmd *cobra.Command, args []string) error {
if !viper.GetBool(flagWithTendermint) {
withTM, _ := cmd.Flags().GetBool(flagWithTendermint)
if !withTM {
ctx.Logger.Info("starting ABCI without Tendermint")
return startStandAlone(ctx, appCreator)
}
@ -89,28 +92,26 @@ which accepts a path for the resulting pprof file.
},
}
// core flags for the ABCI application
cmd.Flags().String(flags.FlagHome, "", "The application home directory")
cmd.Flags().Bool(flagWithTendermint, true, "Run abci app embedded in-process with tendermint")
cmd.Flags().String(flagAddress, "tcp://0.0.0.0:26658", "Listen address")
cmd.Flags().String(flagTraceStore, "", "Enable KVStore tracing to an output file")
cmd.Flags().String(
FlagMinGasPrices, "",
"Minimum gas prices to accept for transactions; Any fee in a tx must meet this minimum (e.g. 0.01photino;0.0001stake)",
)
cmd.Flags().String(FlagMinGasPrices, "", "Minimum gas prices to accept for transactions; Any fee in a tx must meet this minimum (e.g. 0.01photino;0.0001stake)")
cmd.Flags().IntSlice(FlagUnsafeSkipUpgrades, []int{}, "Skip a set of upgrade heights to continue the old binary")
cmd.Flags().Uint64(FlagHaltHeight, 0, "Block height at which to gracefully halt the chain and shutdown the node")
cmd.Flags().Uint64(FlagHaltTime, 0, "Minimum block time (in Unix seconds) at which to gracefully halt the chain and shutdown the node")
cmd.Flags().Bool(FlagInterBlockCache, true, "Enable inter-block caching")
cmd.Flags().String(flagCPUProfile, "", "Enable CPU profiling and write to the provided file")
cmd.Flags().Bool(FlagTrace, false, "Provide full stack traces for errors in ABCI Log")
cmd.Flags().String(FlagPruning, storetypes.PruningOptionDefault, "Pruning strategy (default|nothing|everything|custom)")
cmd.Flags().Uint64(FlagPruningKeepRecent, 0, "Number of recent heights to keep on disk (ignored if pruning is not 'custom')")
cmd.Flags().Uint64(FlagPruningKeepEvery, 0, "Offset heights to keep on disk after 'keep-every' (ignored if pruning is not 'custom')")
cmd.Flags().Uint64(FlagPruningInterval, 0, "Height interval at which pruned heights are removed from disk (ignored if pruning is not 'custom')")
viper.BindPFlag(FlagPruning, cmd.Flags().Lookup(FlagPruning))
viper.BindPFlag(FlagPruningKeepRecent, cmd.Flags().Lookup(FlagPruningKeepRecent))
viper.BindPFlag(FlagPruningKeepEvery, cmd.Flags().Lookup(FlagPruningKeepEvery))
viper.BindPFlag(FlagPruningInterval, cmd.Flags().Lookup(FlagPruningInterval))
cmd.Flags().Uint(FlagInvCheckPeriod, 0, "Assert registered invariants every N blocks")
// Bind flags to the Context's Viper so the app construction can set options
// accordingly.
ctx.Viper.BindPFlags(cmd.Flags())
// add support for all Tendermint-specific command line options
tcmd.AddNodeFlags(cmd)
@ -118,20 +119,21 @@ which accepts a path for the resulting pprof file.
}
func startStandAlone(ctx *Context, appCreator AppCreator) error {
addr := viper.GetString(flagAddress)
home := viper.GetString("home")
traceWriterFile := viper.GetString(flagTraceStore)
addr := ctx.Viper.GetString(flagAddress)
home := ctx.Viper.GetString(flags.FlagHome)
db, err := openDB(home)
if err != nil {
return err
}
traceWriterFile := ctx.Viper.GetString(flagTraceStore)
traceWriter, err := openTraceWriter(traceWriterFile)
if err != nil {
return err
}
app := appCreator(ctx.Logger, db, traceWriter)
app := appCreator(ctx.Logger, db, traceWriter, ctx.Viper)
svr, err := server.NewServer(addr, "socket", app)
if err != nil {
@ -146,7 +148,6 @@ func startStandAlone(ctx *Context, appCreator AppCreator) error {
}
tmos.TrapSignal(ctx.Logger, func() {
// cleanup
err = svr.Stop()
if err != nil {
tmos.Exit(err.Error())
@ -161,7 +162,7 @@ func startInProcess(ctx *Context, cdc codec.JSONMarshaler, appCreator AppCreator
cfg := ctx.Config
home := cfg.RootDir
traceWriterFile := viper.GetString(flagTraceStore)
traceWriterFile := ctx.Viper.GetString(flagTraceStore)
db, err := openDB(home)
if err != nil {
return err
@ -172,7 +173,7 @@ func startInProcess(ctx *Context, cdc codec.JSONMarshaler, appCreator AppCreator
return err
}
app := appCreator(ctx.Logger, db, traceWriter)
app := appCreator(ctx.Logger, db, traceWriter, ctx.Viper)
nodeKey, err := p2p.LoadOrGenNodeKey(cfg.NodeKeyFile())
if err != nil {
@ -180,8 +181,6 @@ func startInProcess(ctx *Context, cdc codec.JSONMarshaler, appCreator AppCreator
}
genDocProvider := node.DefaultGenesisDocProviderFunc(cfg)
// create & start tendermint node
tmNode, err := node.NewNode(
cfg,
pvm.LoadOrGenFilePV(cfg.PrivValidatorKeyFile(), cfg.PrivValidatorStateFile()),
@ -202,16 +201,13 @@ func startInProcess(ctx *Context, cdc codec.JSONMarshaler, appCreator AppCreator
var apiSrv *api.Server
config := config.GetConfig()
config := config.GetConfig(ctx.Viper)
if config.API.Enable {
genDoc, err := genDocProvider()
if err != nil {
return err
}
// TODO: Since this is running in process, do we need to provide a verifier
// and set TrustNode=false? If so, we need to add additional logic that
// waits for a block to be committed first before starting the API server.
clientCtx := client.Context{}.
WithHomeDir(home).
WithChainID(genDoc.ChainID).
@ -239,7 +235,7 @@ func startInProcess(ctx *Context, cdc codec.JSONMarshaler, appCreator AppCreator
var cpuProfileCleanup func()
if cpuProfile := viper.GetString(flagCPUProfile); cpuProfile != "" {
if cpuProfile := ctx.Viper.GetString(flagCPUProfile); cpuProfile != "" {
f, err := os.Create(cpuProfile)
if err != nil {
return err

View File

@ -2,15 +2,7 @@ package server
import (
"fmt"
"io/ioutil"
"net"
"os"
"testing"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/spf13/viper"
"github.com/stretchr/testify/require"
)
// Get a free address for a test tendermint server
@ -36,21 +28,3 @@ func FreeTCPAddr() (addr, port string, err error) {
addr = fmt.Sprintf("tcp://0.0.0.0:%s", port)
return
}
// SetupViper creates a homedir to run inside,
// and returns a cleanup function to defer
func SetupViper(t *testing.T) func() {
rootDir, err := ioutil.TempDir("", "mock-sdk-cmd")
require.Nil(t, err)
viper.Set(flags.FlagHome, rootDir)
viper.Set(flags.FlagName, "moniker")
return func() {
err := os.RemoveAll(rootDir)
if err != nil {
// TODO: Handle with #870
panic(err)
}
}
}
// DONTCOVER

View File

@ -4,9 +4,9 @@ package server
import (
"fmt"
"strings"
"github.com/spf13/cobra"
"github.com/spf13/viper"
yaml "gopkg.in/yaml.v2"
tcmd "github.com/tendermint/tendermint/cmd/tendermint/commands"
@ -51,7 +51,8 @@ func ShowValidatorCmd(ctx *Context) *cobra.Command {
return err
}
if viper.GetString(cli.OutputFlag) == "json" {
output, _ := cmd.Flags().GetString(cli.OutputFlag)
if strings.ToLower(output) == "json" {
return printlnJSON(valPubKey)
}
@ -75,13 +76,12 @@ func ShowAddressCmd(ctx *Context) *cobra.Command {
Use: "show-address",
Short: "Shows this node's tendermint validator consensus address",
RunE: func(cmd *cobra.Command, args []string) error {
cfg := ctx.Config
privValidator := pvm.LoadOrGenFilePV(
cfg.PrivValidatorKeyFile(), cfg.PrivValidatorStateFile())
privValidator := pvm.LoadOrGenFilePV(cfg.PrivValidatorKeyFile(), cfg.PrivValidatorStateFile())
valConsAddr := (sdk.ConsAddress)(privValidator.GetAddress())
if viper.GetString(cli.OutputFlag) == "json" {
output, _ := cmd.Flags().GetString(cli.OutputFlag)
if strings.ToLower(output) == "json" {
return printlnJSON(valConsAddr)
}

View File

@ -2,6 +2,8 @@ package server
import (
"encoding/json"
"errors"
"fmt"
"net"
"os"
"os/signal"
@ -9,14 +11,10 @@ import (
"syscall"
"time"
"errors"
"github.com/spf13/cobra"
"github.com/spf13/viper"
tcmd "github.com/tendermint/tendermint/cmd/tendermint/commands"
cfg "github.com/tendermint/tendermint/config"
"github.com/tendermint/tendermint/libs/cli"
tmcfg "github.com/tendermint/tendermint/config"
tmcli "github.com/tendermint/tendermint/libs/cli"
tmflags "github.com/tendermint/tendermint/libs/cli/flags"
"github.com/tendermint/tendermint/libs/log"
@ -26,105 +24,122 @@ import (
"github.com/cosmos/cosmos-sdk/version"
)
// DONTCOVER
// server context
type Context struct {
Config *cfg.Config
Viper *viper.Viper
Config *tmcfg.Config
Logger log.Logger
}
func NewDefaultContext() *Context {
return NewContext(
cfg.DefaultConfig(),
log.NewTMLogger(log.NewSyncWriter(os.Stdout)),
)
return NewContext(viper.New(), tmcfg.DefaultConfig(), log.NewTMLogger(log.NewSyncWriter(os.Stdout)))
}
func NewContext(config *cfg.Config, logger log.Logger) *Context {
return &Context{config, logger}
func NewContext(v *viper.Viper, config *tmcfg.Config, logger log.Logger) *Context {
return &Context{v, config, logger}
}
//___________________________________________________________________________________
// PersistentPreRunEFn returns a PersistentPreRunE function for cobra
// that initailizes the passed in context with a properly configured
// logger and config object.
func PersistentPreRunEFn(context *Context) func(*cobra.Command, []string) error {
// PersistentPreRunEFn returns a PersistentPreRunE function for the root daemon
// application command. The provided context is typically the default context,
// where the logger and config are set based on the execution of parsing or
// creating a new Tendermint configuration file (config.toml). The provided
// viper object must be created at the root level and have all necessary flags,
// defined by Tendermint, bound to it.
func PersistentPreRunEFn(ctx *Context) func(*cobra.Command, []string) error {
return func(cmd *cobra.Command, args []string) error {
rootViper := viper.New()
rootViper.BindPFlags(cmd.Flags())
rootViper.BindPFlags(cmd.PersistentFlags())
if cmd.Name() == version.Cmd.Name() {
return nil
}
config, err := interceptLoadConfig()
config, err := interceptConfigs(ctx, rootViper)
if err != nil {
return err
}
logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout))
logger, err = tmflags.ParseLogLevel(config.LogLevel, logger, cfg.DefaultLogLevel())
logger, err = tmflags.ParseLogLevel(config.LogLevel, logger, tmcfg.DefaultLogLevel())
if err != nil {
return err
}
if viper.GetBool(cli.TraceFlag) {
if rootViper.GetBool(tmcli.TraceFlag) {
logger = log.NewTracingLogger(logger)
}
logger = logger.With("module", "main")
context.Config = config
context.Logger = logger
ctx.Config = config
ctx.Logger = logger
return nil
}
}
// If a new config is created, change some of the default tendermint settings
func interceptLoadConfig() (conf *cfg.Config, err error) {
tmpConf := cfg.DefaultConfig()
err = viper.Unmarshal(tmpConf)
if err != nil {
// TODO: Handle with #870
panic(err)
}
rootDir := tmpConf.RootDir
configFilePath := filepath.Join(rootDir, "config/config.toml")
// Intercept only if the file doesn't already exist
// interceptConfigs parses and updates a Tendermint configuration file or
// creates a new one and saves it. It also parses and saves the application
// configuration file. The Tendermint configuration file is parsed given a root
// Viper object, whereas the application is parsed with the private package-aware
// viperCfg object.
func interceptConfigs(ctx *Context, rootViper *viper.Viper) (*tmcfg.Config, error) {
rootDir := rootViper.GetString(flags.FlagHome)
configPath := filepath.Join(rootDir, "config")
configFile := filepath.Join(configPath, "config.toml")
conf := tmcfg.DefaultConfig()
if _, err := os.Stat(configFile); os.IsNotExist(err) {
tmcfg.EnsureRoot(rootDir)
if err = conf.ValidateBasic(); err != nil {
return nil, fmt.Errorf("error in config file: %v", err)
}
if _, err := os.Stat(configFilePath); os.IsNotExist(err) {
// the following parse config is needed to create directories
conf, _ = tcmd.ParseConfig() // NOTE: ParseConfig() creates dir/files as necessary.
conf.ProfListenAddress = "localhost:6060"
conf.P2P.RecvRate = 5120000
conf.P2P.SendRate = 5120000
conf.TxIndex.IndexAllKeys = true
conf.Consensus.TimeoutCommit = 5 * time.Second
cfg.WriteConfigFile(configFilePath, conf)
// Fall through, just so that its parsed into memory.
}
tmcfg.WriteConfigFile(configFile, conf)
} else {
rootViper.SetConfigType("toml")
rootViper.SetConfigName("config")
rootViper.AddConfigPath(configPath)
if err := rootViper.ReadInConfig(); err != nil {
return nil, fmt.Errorf("failed to read in app.toml: %w", err)
}
if conf == nil {
conf, err = tcmd.ParseConfig() // NOTE: ParseConfig() creates dir/files as necessary.
if err != nil {
panic(err)
if err := rootViper.Unmarshal(conf); err != nil {
return nil, err
}
}
appConfigFilePath := filepath.Join(rootDir, "config/app.toml")
appConfigFilePath := filepath.Join(configPath, "app.toml")
if _, err := os.Stat(appConfigFilePath); os.IsNotExist(err) {
appConf, _ := config.ParseConfig()
appConf, err := config.ParseConfig(ctx.Viper)
if err != nil {
return nil, fmt.Errorf("failed to parse app.toml: %w", err)
}
config.WriteConfigFile(appConfigFilePath, appConf)
}
viper.SetConfigName("app")
err = viper.MergeInConfig()
ctx.Viper.SetConfigType("toml")
ctx.Viper.SetConfigName("app")
ctx.Viper.AddConfigPath(configPath)
if err := ctx.Viper.ReadInConfig(); err != nil {
return nil, fmt.Errorf("failed to read in app.toml: %w", err)
}
return conf, err
return conf, nil
}
// add server commands
func AddCommands(
ctx *Context, cdc codec.JSONMarshaler, rootCmd *cobra.Command, appCreator AppCreator, appExport AppExporter,
) {
func AddCommands(ctx *Context, cdc codec.JSONMarshaler, rootCmd *cobra.Command, appCreator AppCreator, appExport AppExporter) {
rootCmd.PersistentFlags().String("log_level", ctx.Config.LogLevel, "Log level")
tendermintCmd := &cobra.Command{
@ -150,8 +165,6 @@ func AddCommands(
)
}
//___________________________________________________________________________________
// InsertKeyJSON inserts a new JSON field/key with a given value to an existing
// JSON message. An error is returned if any serialization operation fails.
//
@ -249,5 +262,3 @@ func addrToIP(addr net.Addr) net.IP {
}
return ip
}
// DONTCOVER

View File

@ -5,14 +5,11 @@ import (
"errors"
"fmt"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/tendermint/tendermint/libs/cli"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/crypto/keyring"
"github.com/cosmos/cosmos-sdk/server"
sdk "github.com/cosmos/cosmos-sdk/types"
@ -31,10 +28,7 @@ const (
)
// AddGenesisAccountCmd returns add-genesis-account cobra Command.
func AddGenesisAccountCmd(
ctx *server.Context, depCdc codec.JSONMarshaler, cdc codec.Marshaler, defaultNodeHome, defaultClientHome string,
) *cobra.Command {
func AddGenesisAccountCmd(ctx *server.Context, depCdc codec.JSONMarshaler, cdc codec.Marshaler, defaultClientHome string) *cobra.Command {
cmd := &cobra.Command{
Use: "add-genesis-account [address_or_key_name] [coin][,[coin]]",
Short: "Add a genesis account to genesis.json",
@ -46,18 +40,17 @@ contain valid denominations. Accounts may optionally be supplied with vesting pa
Args: cobra.ExactArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {
config := ctx.Config
config.SetRoot(viper.GetString(cli.HomeFlag))
homeDir, _ := cmd.Flags().GetString(cli.HomeFlag)
config.SetRoot(homeDir)
keyringBackend, _ := cmd.Flags().GetString(flags.FlagKeyringBackend)
clientHome, _ := cmd.Flags().GetString(flagClientHome)
addr, err := sdk.AccAddressFromBech32(args[0])
inBuf := bufio.NewReader(cmd.InOrStdin())
if err != nil {
// attempt to lookup address from Keybase if no address was provided
kb, err := keyring.New(
sdk.KeyringServiceName(),
viper.GetString(flags.FlagKeyringBackend),
viper.GetString(flagClientHome),
inBuf,
)
kb, err := keyring.New(sdk.KeyringServiceName(), keyringBackend, clientHome, inBuf)
if err != nil {
return err
}
@ -75,9 +68,11 @@ contain valid denominations. Accounts may optionally be supplied with vesting pa
return fmt.Errorf("failed to parse coins: %w", err)
}
vestingStart := viper.GetInt64(flagVestingStart)
vestingEnd := viper.GetInt64(flagVestingEnd)
vestingAmt, err := sdk.ParseCoins(viper.GetString(flagVestingAmt))
vestingStart, _ := cmd.Flags().GetInt64(flagVestingStart)
vestingEnd, _ := cmd.Flags().GetInt64(flagVestingEnd)
vestingAmtStr, _ := cmd.Flags().GetString(flagVestingAmt)
vestingAmt, err := sdk.ParseCoins(vestingAmtStr)
if err != nil {
return fmt.Errorf("failed to parse vesting amount: %w", err)
}
@ -159,12 +154,11 @@ contain valid denominations. Accounts may optionally be supplied with vesting pa
},
}
cmd.Flags().String(cli.HomeFlag, defaultNodeHome, "node's home directory")
cmd.Flags().String(flags.FlagKeyringBackend, flags.DefaultKeyringBackend, "Select keyring's backend (os|file|test)")
cmd.Flags().String(flags.FlagHome, "", "The application home directory")
cmd.Flags().String(flagClientHome, defaultClientHome, "client's home directory")
cmd.Flags().String(flagVestingAmt, "", "amount of coins for vesting accounts")
cmd.Flags().Uint64(flagVestingStart, 0, "schedule start time (unix epoch) for vesting accounts")
cmd.Flags().Uint64(flagVestingEnd, 0, "schedule end time (unix epoch) for vesting accounts")
cmd.Flags().Int64(flagVestingStart, 0, "schedule start time (unix epoch) for vesting accounts")
cmd.Flags().Int64(flagVestingEnd, 0, "schedule end time (unix epoch) for vesting accounts")
return cmd
}

View File

@ -4,6 +4,7 @@ import (
"encoding/json"
"io"
"github.com/spf13/cast"
"github.com/spf13/cobra"
"github.com/spf13/viper"
abci "github.com/tendermint/tendermint/abci/types"
@ -24,9 +25,7 @@ import (
"github.com/cosmos/cosmos-sdk/x/staking"
)
const flagInvCheckPeriod = "inv-check-period"
var invCheckPeriod uint
var viperCfg = viper.New()
func main() {
appCodec, cdc := simapp.MakeCodecs()
@ -45,6 +44,9 @@ func main() {
PersistentPreRunE: server.PersistentPreRunEFn(ctx),
}
rootCmd.PersistentFlags().String(flags.FlagKeyringBackend, flags.DefaultKeyringBackend, "Select keyring's backend (os|file|test)")
viperCfg.BindPFlags(rootCmd.Flags())
rootCmd.AddCommand(
genutilcli.InitCmd(ctx, cdc, simapp.ModuleBasics, simapp.DefaultNodeHome),
genutilcli.CollectGenTxsCmd(ctx, cdc, banktypes.GenesisBalancesIterator{}, simapp.DefaultNodeHome),
@ -54,49 +56,47 @@ func main() {
banktypes.GenesisBalancesIterator{}, simapp.DefaultNodeHome, simapp.DefaultCLIHome,
),
genutilcli.ValidateGenesisCmd(ctx, cdc, simapp.ModuleBasics),
AddGenesisAccountCmd(ctx, cdc, appCodec, simapp.DefaultNodeHome, simapp.DefaultCLIHome),
AddGenesisAccountCmd(ctx, cdc, appCodec, simapp.DefaultCLIHome),
flags.NewCompletionCmd(rootCmd, true),
testnetCmd(ctx, cdc, simapp.ModuleBasics, banktypes.GenesisBalancesIterator{}),
debug.Cmd(cdc))
debug.Cmd(cdc),
)
server.AddCommands(ctx, cdc, rootCmd, newApp, exportAppStateAndTMValidators)
// prepare and add flags
executor := cli.PrepareBaseCmd(rootCmd, "GA", simapp.DefaultNodeHome)
rootCmd.PersistentFlags().UintVar(&invCheckPeriod, flagInvCheckPeriod,
0, "Assert registered invariants every N blocks")
err := executor.Execute()
if err != nil {
executor := cli.PrepareBaseCmd(rootCmd, "", simapp.DefaultNodeHome)
if err := executor.Execute(); err != nil {
panic(err)
}
}
func newApp(logger log.Logger, db dbm.DB, traceStore io.Writer) server.Application {
func newApp(logger log.Logger, db dbm.DB, traceStore io.Writer, appOpts server.AppOptions) server.Application {
var cache sdk.MultiStorePersistentCache
if viper.GetBool(server.FlagInterBlockCache) {
if cast.ToBool(appOpts.Get(server.FlagInterBlockCache)) {
cache = store.NewCommitKVStoreCacheManager()
}
skipUpgradeHeights := make(map[int64]bool)
for _, h := range viper.GetIntSlice(server.FlagUnsafeSkipUpgrades) {
for _, h := range cast.ToIntSlice(appOpts.Get(server.FlagUnsafeSkipUpgrades)) {
skipUpgradeHeights[int64(h)] = true
}
pruningOpts, err := server.GetPruningOptionsFromFlags()
pruningOpts, err := server.GetPruningOptionsFromFlags(appOpts)
if err != nil {
panic(err)
}
// TODO: Make sure custom pruning works.
return simapp.NewSimApp(
logger, db, traceStore, true, skipUpgradeHeights,
viper.GetString(flags.FlagHome), invCheckPeriod,
cast.ToString(appOpts.Get(flags.FlagHome)),
cast.ToUint(appOpts.Get(server.FlagInvCheckPeriod)),
baseapp.SetPruning(pruningOpts),
baseapp.SetMinGasPrices(viper.GetString(server.FlagMinGasPrices)),
baseapp.SetHaltHeight(viper.GetUint64(server.FlagHaltHeight)),
baseapp.SetHaltTime(viper.GetUint64(server.FlagHaltTime)),
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))),
)
}
@ -107,12 +107,13 @@ func exportAppStateAndTMValidators(
var simApp *simapp.SimApp
if height != -1 {
simApp = simapp.NewSimApp(logger, db, traceStore, false, map[int64]bool{}, "", uint(1))
err := simApp.LoadHeight(height)
if err != nil {
if err := simApp.LoadHeight(height); err != nil {
return nil, nil, nil, err
}
} else {
simApp = simapp.NewSimApp(logger, db, traceStore, true, map[int64]bool{}, "", uint(1))
}
return simApp.ExportAppStateAndValidators(forZeroHeight, jailWhiteList)
}

View File

@ -11,7 +11,6 @@ import (
"path/filepath"
"github.com/spf13/cobra"
"github.com/spf13/viper"
tmconfig "github.com/tendermint/tendermint/config"
"github.com/tendermint/tendermint/crypto"
tmos "github.com/tendermint/tendermint/libs/os"
@ -62,39 +61,31 @@ Example:
RunE: func(cmd *cobra.Command, _ []string) error {
config := ctx.Config
outputDir := viper.GetString(flagOutputDir)
chainID := viper.GetString(flags.FlagChainID)
minGasPrices := viper.GetString(server.FlagMinGasPrices)
nodeDirPrefix := viper.GetString(flagNodeDirPrefix)
nodeDaemonHome := viper.GetString(flagNodeDaemonHome)
nodeCLIHome := viper.GetString(flagNodeCLIHome)
startingIPAddress := viper.GetString(flagStartingIPAddress)
numValidators := viper.GetInt(flagNumValidators)
outputDir, _ := cmd.Flags().GetString(flagOutputDir)
keyringBackend, _ := cmd.Flags().GetString(flags.FlagKeyringBackend)
chainID, _ := cmd.Flags().GetString(flags.FlagChainID)
minGasPrices, _ := cmd.Flags().GetString(server.FlagMinGasPrices)
nodeDirPrefix, _ := cmd.Flags().GetString(flagNodeDirPrefix)
nodeDaemonHome, _ := cmd.Flags().GetString(flagNodeDaemonHome)
nodeCLIHome, _ := cmd.Flags().GetString(flagNodeCLIHome)
startingIPAddress, _ := cmd.Flags().GetString(flagStartingIPAddress)
numValidators, _ := cmd.Flags().GetInt(flagNumValidators)
return InitTestnet(
cmd, config, cdc, mbm, genBalIterator, outputDir, chainID, minGasPrices,
nodeDirPrefix, nodeDaemonHome, nodeCLIHome, startingIPAddress, numValidators,
nodeDirPrefix, nodeDaemonHome, nodeCLIHome, startingIPAddress, keyringBackend, numValidators,
)
},
}
cmd.Flags().Int(flagNumValidators, 4,
"Number of validators to initialize the testnet with")
cmd.Flags().StringP(flagOutputDir, "o", "./mytestnet",
"Directory to store initialization data for the testnet")
cmd.Flags().String(flagNodeDirPrefix, "node",
"Prefix the directory name for each node with (node results in node0, node1, ...)")
cmd.Flags().String(flagNodeDaemonHome, "simd",
"Home directory of the node's daemon configuration")
cmd.Flags().String(flagNodeCLIHome, "simcli",
"Home directory of the node's cli configuration")
cmd.Flags().String(flagStartingIPAddress, "192.168.0.1",
"Starting IP address (192.168.0.1 results in persistent peers list ID0@192.168.0.1:46656, ID1@192.168.0.2:46656, ...)")
cmd.Flags().String(
flags.FlagChainID, "", "genesis file chain-id, if left blank will be randomly created")
cmd.Flags().String(
server.FlagMinGasPrices, fmt.Sprintf("0.000006%s", sdk.DefaultBondDenom),
"Minimum gas prices to accept for transactions; All fees in a tx must meet this minimum (e.g. 0.01photino,0.001stake)")
cmd.Flags().Int(flagNumValidators, 4, "Number of validators to initialize the testnet with")
cmd.Flags().StringP(flagOutputDir, "o", "./mytestnet", "Directory to store initialization data for the testnet")
cmd.Flags().String(flagNodeDirPrefix, "node", "Prefix the directory name for each node with (node results in node0, node1, ...)")
cmd.Flags().String(flagNodeDaemonHome, "simd", "Home directory of the node's daemon configuration")
cmd.Flags().String(flagNodeCLIHome, "simcli", "Home directory of the node's cli configuration")
cmd.Flags().String(flagStartingIPAddress, "192.168.0.1", "Starting IP address (192.168.0.1 results in persistent peers list ID0@192.168.0.1:46656, ID1@192.168.0.2:46656, ...)")
cmd.Flags().String(flags.FlagChainID, "", "genesis file chain-id, if left blank will be randomly created")
cmd.Flags().String(server.FlagMinGasPrices, fmt.Sprintf("0.000006%s", sdk.DefaultBondDenom), "Minimum gas prices to accept for transactions; All fees in a tx must meet this minimum (e.g. 0.01photino,0.001stake)")
cmd.Flags().String(flags.FlagKeyringBackend, flags.DefaultKeyringBackend, "Select keyring's backend (os|file|test)")
return cmd
@ -107,7 +98,7 @@ func InitTestnet(
cmd *cobra.Command, config *tmconfig.Config, cdc codec.JSONMarshaler,
mbm module.BasicManager, genBalIterator banktypes.GenesisBalancesIterator,
outputDir, chainID, minGasPrices, nodeDirPrefix, nodeDaemonHome,
nodeCLIHome, startingIPAddress string, numValidators int,
nodeCLIHome, startingIPAddress, keyringBackend string, numValidators int,
) error {
if chainID == "" {
@ -171,12 +162,7 @@ func InitTestnet(
memo := fmt.Sprintf("%s@%s:26656", nodeIDs[i], ip)
genFiles = append(genFiles, config.GenesisFile())
kb, err := keyring.New(
sdk.KeyringServiceName(),
viper.GetString(flags.FlagKeyringBackend),
clientDir,
inBuf,
)
kb, err := keyring.New(sdk.KeyringServiceName(), keyringBackend, clientDir, inBuf)
if err != nil {
return err
}

View File

@ -1,7 +1,6 @@
package errors
import (
"errors"
"fmt"
"reflect"
@ -18,8 +17,6 @@ const (
// detailed error string.
internalABCICodespace = UndefinedCodespace
internalABCICode uint32 = 1
internalABCILog string = "internal error"
// multiErrorABCICode uint32 = 1000
)
// ABCIInfo returns the ABCI error information as consumed by the tendermint
@ -44,8 +41,8 @@ func ABCIInfo(err error, debug bool) (codespace string, code uint32, log string)
// ResponseCheckTx returns an ABCI ResponseCheckTx object with fields filled in
// from the given error and gas values.
func ResponseCheckTx(err error, gw, gu uint64) abci.ResponseCheckTx {
space, code, log := ABCIInfo(err, false)
func ResponseCheckTx(err error, gw, gu uint64, debug bool) abci.ResponseCheckTx {
space, code, log := ABCIInfo(err, debug)
return abci.ResponseCheckTx{
Codespace: space,
Code: code,
@ -57,8 +54,8 @@ func ResponseCheckTx(err error, gw, gu uint64) abci.ResponseCheckTx {
// ResponseDeliverTx returns an ABCI ResponseDeliverTx object with fields filled in
// from the given error and gas values.
func ResponseDeliverTx(err error, gw, gu uint64) abci.ResponseDeliverTx {
space, code, log := ABCIInfo(err, false)
func ResponseDeliverTx(err error, gw, gu uint64, debug bool) abci.ResponseDeliverTx {
space, code, log := ABCIInfo(err, debug)
return abci.ResponseDeliverTx{
Codespace: space,
Code: code,
@ -159,10 +156,11 @@ func errIsNil(err error) bool {
// simply returned.
func Redact(err error) error {
if ErrPanic.Is(err) {
return errors.New(internalABCILog)
return ErrPanic
}
if abciCode(err) == internalABCICode {
return errors.New(internalABCILog)
return errInternal
}
return err
}

View File

@ -7,7 +7,6 @@ import (
"testing"
"github.com/stretchr/testify/require"
abci "github.com/tendermint/tendermint/abci/types"
)
func TestABCInfo(t *testing.T) {
@ -49,7 +48,7 @@ func TestABCInfo(t *testing.T) {
"stdlib is generic message": {
err: io.EOF,
debug: false,
wantLog: "internal error",
wantLog: "internal",
wantCode: 1,
wantSpace: UndefinedCodespace,
},
@ -63,7 +62,7 @@ func TestABCInfo(t *testing.T) {
"wrapped stdlib is only a generic message": {
err: Wrap(io.EOF, "cannot read file"),
debug: false,
wantLog: "internal error",
wantLog: "internal",
wantCode: 1,
wantSpace: UndefinedCodespace,
},
@ -95,9 +94,15 @@ func TestABCInfo(t *testing.T) {
tc := tc
t.Run(testName, func(t *testing.T) {
space, code, log := ABCIInfo(tc.err, tc.debug)
require.Equal(t, tc.wantSpace, space)
require.Equal(t, tc.wantCode, code)
require.Equal(t, tc.wantLog, log)
if space != tc.wantSpace {
t.Errorf("want %s space, got %s", tc.wantSpace, space)
}
if code != tc.wantCode {
t.Errorf("want %d code, got %d", tc.wantCode, code)
}
if log != tc.wantLog {
t.Errorf("want %q log, got %q", tc.wantLog, log)
}
})
}
}
@ -131,7 +136,7 @@ func TestABCIInfoStacktrace(t *testing.T) {
err: Wrap(fmt.Errorf("stdlib"), "wrapped"),
debug: false,
wantStacktrace: false,
wantErrMsg: "internal error",
wantErrMsg: "internal",
},
}
@ -159,28 +164,50 @@ func TestABCIInfoStacktrace(t *testing.T) {
func TestABCIInfoHidesStacktrace(t *testing.T) {
err := Wrap(ErrUnauthorized, "wrapped")
_, _, log := ABCIInfo(err, false)
require.Equal(t, "wrapped: unauthorized", log)
if log != "wrapped: unauthorized" {
t.Fatalf("unexpected message in non debug mode: %s", log)
}
}
func TestRedact(t *testing.T) {
if err := Redact(ErrPanic); ErrPanic.Is(err) {
t.Error("reduct must not pass through panic error")
}
if err := Redact(ErrUnauthorized); !ErrUnauthorized.Is(err) {
t.Error("reduct should pass through SDK error")
cases := map[string]struct {
err error
untouched bool // if true we expect the same error after redact
changed error // if untouched == false, expect this error
}{
"panic looses message": {
err: Wrap(ErrPanic, "some secret stack trace"),
changed: ErrPanic,
},
"sdk errors untouched": {
err: Wrap(ErrUnauthorized, "cannot drop db"),
untouched: true,
},
"pass though custom errors with ABCI code": {
err: customErr{},
untouched: true,
},
"redact stdlib error": {
err: fmt.Errorf("stdlib error"),
changed: errInternal,
},
}
var cerr customErr
if err := Redact(cerr); err != cerr {
t.Error("reduct should pass through ABCI code error")
for name, tc := range cases {
spec := tc
t.Run(name, func(t *testing.T) {
redacted := Redact(spec.err)
if spec.untouched {
require.Equal(t, spec.err, redacted)
} else {
// see if we got the expected redact
require.Equal(t, spec.changed, redacted)
// make sure the ABCI code did not change
require.Equal(t, abciCode(spec.err), abciCode(redacted))
}
})
}
serr := fmt.Errorf("stdlib error")
if err := Redact(serr); err == serr {
t.Error("reduct must not pass through a stdlib error")
}
require.Nil(t, Redact(nil))
}
func TestABCIInfoSerializeErr(t *testing.T) {
@ -211,47 +238,23 @@ func TestABCIInfoSerializeErr(t *testing.T) {
debug: true,
exp: fmt.Sprintf("%+v", myErrDecode),
},
// "multi error default encoder": {
// src: Append(myErrMsg, myErrAddr),
// exp: Append(myErrMsg, myErrAddr).Error(),
// },
// "multi error default with internal": {
// src: Append(myErrMsg, myPanic),
// exp: "internal error",
// },
"redact in default encoder": {
src: myPanic,
exp: "internal error",
exp: "panic",
},
"do not redact in debug encoder": {
src: myPanic,
debug: true,
exp: fmt.Sprintf("%+v", myPanic),
},
// "redact in multi error": {
// src: Append(myPanic, myErrMsg),
// debug: false,
// exp: "internal error",
// },
// "no redact in multi error": {
// src: Append(myPanic, myErrMsg),
// debug: true,
// exp: `2 errors occurred:
// * panic
// * test: invalid message
// `,
// },
// "wrapped multi error with redact": {
// src: Wrap(Append(myPanic, myErrMsg), "wrap"),
// debug: false,
// exp: "internal error",
// },
}
for msg, spec := range specs {
spec := spec
t.Run(msg, func(t *testing.T) {
_, _, log := ABCIInfo(spec.src, spec.debug)
require.Equal(t, spec.exp, log)
if exp, got := spec.exp, log; exp != got {
t.Errorf("expected %v but got %v", exp, got)
}
})
}
}
@ -265,30 +268,3 @@ func (customErr) Codespace() string { return "extern" }
func (customErr) ABCICode() uint32 { return 999 }
func (customErr) Error() string { return "custom" }
func TestResponseCheckDeliverTx(t *testing.T) {
t.Parallel()
require.Equal(t, abci.ResponseCheckTx{
Codespace: "extern",
Code: 999,
Log: "custom",
GasWanted: int64(1),
GasUsed: int64(2),
}, ResponseCheckTx(customErr{}, 1, 2))
require.Equal(t, abci.ResponseDeliverTx{
Codespace: "extern",
Code: 999,
Log: "custom",
GasWanted: int64(1),
GasUsed: int64(2),
}, ResponseDeliverTx(customErr{}, 1, 2))
}
func TestQueryResult(t *testing.T) {
t.Parallel()
require.Equal(t, abci.ResponseQuery{
Codespace: "extern",
Code: 999,
Log: "custom",
}, QueryResult(customErr{}))
}

View File

@ -27,6 +27,7 @@ func CollectGenTxsCmd(ctx *server.Context, cdc codec.JSONMarshaler, genBalIterat
RunE: func(_ *cobra.Command, _ []string) error {
config := ctx.Config
config.SetRoot(viper.GetString(cli.HomeFlag))
name := viper.GetString(flags.FlagName)
nodeID, valPubKey, err := genutil.InitializeNodeValidatorFiles(config)
if err != nil {
@ -59,9 +60,7 @@ func CollectGenTxsCmd(ctx *server.Context, cdc codec.JSONMarshaler, genBalIterat
}
cmd.Flags().String(cli.HomeFlag, defaultNodeHome, "node's home directory")
cmd.Flags().String(flagGenTxDir, "",
"override default \"gentx\" directory from which collect and execute "+
"genesis transactions; default [--home]/config/gentx/")
cmd.Flags().String(flagGenTxDir, "", "override default \"gentx\" directory from which collect and execute genesis transactions; default [--home]/config/gentx/")
return cmd
}

View File

@ -28,8 +28,7 @@ import (
var testMbm = module.NewBasicManager(genutil.AppModuleBasic{})
func TestInitCmd(t *testing.T) {
t.Cleanup(server.SetupViper(t))
t.Cleanup(server.SetupViper(t))
t.SkipNow()
home, cleanup := tests.NewTestCaseDir(t)
t.Cleanup(cleanup)
@ -37,7 +36,7 @@ func TestInitCmd(t *testing.T) {
cfg, err := tcmd.ParseConfig()
require.Nil(t, err)
ctx := server.NewContext(cfg, logger)
ctx := server.NewContext(viper.New(), cfg, logger)
cdc := makeCodec()
cmd := InitCmd(ctx, cdc, testMbm, home)
@ -51,7 +50,7 @@ func setupClientHome(t *testing.T) func() {
}
func TestEmptyState(t *testing.T) {
t.Cleanup(server.SetupViper(t))
t.SkipNow()
t.Cleanup(setupClientHome(t))
home, cleanup := tests.NewTestCaseDir(t)
@ -61,7 +60,7 @@ func TestEmptyState(t *testing.T) {
cfg, err := tcmd.ParseConfig()
require.Nil(t, err)
ctx := server.NewContext(cfg, logger)
ctx := server.NewContext(viper.New(), cfg, logger)
cdc := makeCodec()
cmd := InitCmd(ctx, cdc, testMbm, home)
@ -102,7 +101,7 @@ func TestStartStandAlone(t *testing.T) {
logger := log.NewNopLogger()
cfg, err := tcmd.ParseConfig()
require.Nil(t, err)
ctx := server.NewContext(cfg, logger)
ctx := server.NewContext(viper.New(), cfg, logger)
cdc := makeCodec()
initCmd := InitCmd(ctx, cdc, testMbm, home)
require.NoError(t, initCmd.RunE(nil, []string{"appnode-test"}))

View File

@ -44,7 +44,7 @@ func TestMigrateGenesis(t *testing.T) {
logger := log.NewNopLogger()
cfg, err := tcmd.ParseConfig()
require.Nil(t, err)
ctx := server.NewContext(cfg, logger)
ctx := server.NewContext(viper.New(), cfg, logger)
cdc := makeCodec()
genesisPath := path.Join(home, "genesis.json")

View File

@ -15,11 +15,11 @@ import (
)
func TestPrepareFlagsForTxCreateValidator(t *testing.T) {
defer server.SetupViper(t)()
t.SkipNow()
config, err := tcmd.ParseConfig()
require.Nil(t, err)
logger := log.NewNopLogger()
ctx := server.NewContext(config, logger)
ctx := server.NewContext(viper.New(), config, logger)
valPubKey, _ := sdk.GetPubKeyFromBech32(sdk.Bech32PubKeyTypeConsPub, "cosmosvalconspub1zcjduepq7jsrkl9fgqk0wj3ahmfr8pgxj6vakj2wzn656s8pehh0zhv2w5as5gd80a")