From 9fbb8e8fb80ba27f39120da08c732cff57344f2e Mon Sep 17 00:00:00 2001 From: Hieu Vu <72878483+hieuvubk@users.noreply.github.com> Date: Thu, 23 May 2024 15:29:52 +0700 Subject: [PATCH] revert: server v0 use Context --- server/cmd/execute.go | 11 +-- server/cmt_cmds.go | 22 +++--- server/rollback.go | 11 +-- server/start.go | 172 ++++++++++++++++++++---------------------- server/util.go | 124 +++++++++++++++++------------- server/util_test.go | 96 +++++++++++------------ 6 files changed, 215 insertions(+), 221 deletions(-) diff --git a/server/cmd/execute.go b/server/cmd/execute.go index 321512bd551c..cf8e7c009f44 100644 --- a/server/cmd/execute.go +++ b/server/cmd/execute.go @@ -2,18 +2,14 @@ package cmd import ( "context" - "os" cmtcli "github.com/cometbft/cometbft/libs/cli" "github.com/rs/zerolog" "github.com/spf13/cobra" - "github.com/spf13/viper" - - corectx "cosmossdk.io/core/context" - "cosmossdk.io/log" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/server" ) // Execute executes the root command of an application. It handles creating a @@ -41,10 +37,9 @@ func Execute(rootCmd *cobra.Command, envPrefix, defaultHome string) error { // CreateExecuteContext returns a base Context with server and client context // values initialized. func CreateExecuteContext(ctx context.Context) context.Context { - // srvCtx := server.NewDefaultContext() + srvCtx := server.NewDefaultContext() ctx = context.WithValue(ctx, client.ClientContextKey, &client.Context{}) - ctx = context.WithValue(ctx, corectx.LoggerContextKey{}, log.NewLogger(os.Stdout)) - ctx = context.WithValue(ctx, corectx.ViperContextKey{}, viper.New()) + ctx = context.WithValue(ctx, server.ServerContextKey, srvCtx) return ctx } diff --git a/server/cmt_cmds.go b/server/cmt_cmds.go index 1fdd6ca515b4..e4fdf1ed814c 100644 --- a/server/cmt_cmds.go +++ b/server/cmt_cmds.go @@ -16,6 +16,7 @@ import ( "github.com/spf13/cobra" "sigs.k8s.io/yaml" + "cosmossdk.io/log" auth "cosmossdk.io/x/auth/client/cli" "github.com/cosmos/cosmos-sdk/client" @@ -72,7 +73,8 @@ func ShowNodeIDCmd() *cobra.Command { Use: "show-node-id", Short: "Show this node's ID", RunE: func(cmd *cobra.Command, args []string) error { - cfg := client.GetConfigFromCmd(cmd) + serverCtx := GetServerContextFromCmd(cmd) + cfg := serverCtx.Config nodeKey, err := p2p.LoadNodeKey(cfg.NodeKeyFile()) if err != nil { @@ -91,7 +93,8 @@ func ShowValidatorCmd() *cobra.Command { Use: "show-validator", Short: "Show this node's CometBFT validator info", RunE: func(cmd *cobra.Command, args []string) error { - cfg := client.GetConfigFromCmd(cmd) + serverCtx := GetServerContextFromCmd(cmd) + cfg := serverCtx.Config privValidator := pvm.LoadFilePV(cfg.PrivValidatorKeyFile(), cfg.PrivValidatorStateFile()) pk, err := privValidator.GetPubKey() @@ -124,7 +127,8 @@ func ShowAddressCmd() *cobra.Command { Use: "show-address", Short: "Shows this node's CometBFT validator consensus address", RunE: func(cmd *cobra.Command, args []string) error { - cfg := client.GetConfigFromCmd(cmd) + serverCtx := GetServerContextFromCmd(cmd) + cfg := serverCtx.Config privValidator := pvm.LoadFilePV(cfg.PrivValidatorKeyFile(), cfg.PrivValidatorStateFile()) @@ -358,22 +362,22 @@ func BootstrapStateCmd[T types.Application](appCreator types.AppCreator[T]) *cob Short: "Bootstrap CometBFT state at an arbitrary block height using a light client", Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, args []string) error { - cfg := client.GetConfigFromCmd(cmd) - logger := client.GetLoggerFromCmd(cmd) - viper := client.GetViperFromCmd(cmd) + serverCtx := GetServerContextFromCmd(cmd) + logger := log.NewLogger(cmd.OutOrStdout()) + cfg := serverCtx.Config height, err := cmd.Flags().GetInt64("height") if err != nil { return err } if height == 0 { - home := viper.GetString(flags.FlagHome) - db, err := OpenDB(home, GetAppDBBackend(viper)) + home := serverCtx.Viper.GetString(flags.FlagHome) + db, err := OpenDB(home, GetAppDBBackend(serverCtx.Viper)) if err != nil { return err } - app := appCreator(logger, db, nil, viper) + app := appCreator(logger, db, nil, serverCtx.Viper) height = app.CommitMultiStore().LastCommitID().Version } diff --git a/server/rollback.go b/server/rollback.go index 21c5c8e6ed87..7dd58bcedf64 100644 --- a/server/rollback.go +++ b/server/rollback.go @@ -6,7 +6,6 @@ import ( cmtcmd "github.com/cometbft/cometbft/cmd/cometbft/commands" "github.com/spf13/cobra" - "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/server/types" ) @@ -26,17 +25,15 @@ restarting CometBFT the transactions in block n will be re-executed against the application. `, RunE: func(cmd *cobra.Command, args []string) error { - config := client.GetConfigFromCmd(cmd) - logger := client.GetLoggerFromCmd(cmd) - viper := client.GetViperFromCmd(cmd) + ctx := GetServerContextFromCmd(cmd) - db, err := OpenDB(config.RootDir, GetAppDBBackend(viper)) + db, err := OpenDB(ctx.Config.RootDir, GetAppDBBackend(ctx.Viper)) if err != nil { return err } - app := appCreator(logger, db, nil, viper) + app := appCreator(ctx.Logger, db, nil, ctx.Viper) // rollback CometBFT state - height, hash, err := cmtcmd.RollbackState(config, removeBlock) + height, hash, err := cmtcmd.RollbackState(ctx.Config, removeBlock) if err != nil { return fmt.Errorf("failed to rollback CometBFT state: %w", err) } diff --git a/server/start.go b/server/start.go index db7ab63b7730..ea0e43d31319 100644 --- a/server/start.go +++ b/server/start.go @@ -32,7 +32,6 @@ import ( "github.com/hashicorp/go-metrics" "github.com/spf13/cobra" "github.com/spf13/pflag" - "github.com/spf13/viper" "golang.org/x/sync/errgroup" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" @@ -121,13 +120,13 @@ type StartCmdOptions[T types.Application] struct { DBOpener func(rootDir string, backendType dbm.BackendType) (dbm.DB, error) // PostSetup can be used to setup extra services under the same cancellable context, // it's not called in stand-alone mode, only for in-process mode. - PostSetup func(app T, viper *viper.Viper, logger log.Logger, clientCtx client.Context, ctx context.Context, g *errgroup.Group) error + PostSetup func(app T, svrCtx *Context, clientCtx client.Context, ctx context.Context, g *errgroup.Group) error // PostSetupStandalone can be used to setup extra services under the same cancellable context, - PostSetupStandalone func(app T, viper *viper.Viper, logger log.Logger, clientCtx client.Context, ctx context.Context, g *errgroup.Group) error + PostSetupStandalone func(app T, svrCtx *Context, clientCtx client.Context, ctx context.Context, g *errgroup.Group) error // AddFlags add custom flags to start cmd AddFlags func(cmd *cobra.Command) // StartCommandHanlder can be used to customize the start command handler - StartCommandHandler func(viper *viper.Viper, logger log.Logger, clientCtx client.Context, appCreator types.AppCreator[T], inProcessConsensus bool, opts StartCmdOptions[T]) error + StartCommandHandler func(svrCtx *Context, clientCtx client.Context, appCreator types.AppCreator[T], inProcessConsensus bool, opts StartCmdOptions[T]) error } // StartCmd runs the service passed in, either stand-alone or in-process with @@ -178,10 +177,8 @@ bypassed and can be used when legacy queries are needed after an on-chain upgrad is performed. Note, when enabled, gRPC will also be automatically enabled. `, RunE: func(cmd *cobra.Command, _ []string) error { - viper := client.GetViperFromCmd(cmd) - logger := client.GetLoggerFromCmd(cmd) - - _, err := GetPruningOptionsFromFlags(viper) + serverCtx := GetServerContextFromCmd(cmd) + _, err := GetPruningOptionsFromFlags(serverCtx.Viper) if err != nil { return err } @@ -193,19 +190,19 @@ is performed. Note, when enabled, gRPC will also be automatically enabled. withCMT, _ := cmd.Flags().GetBool(flagWithComet) if !withCMT { - logger.Info("starting ABCI without CometBFT") + serverCtx.Logger.Info("starting ABCI without CometBFT") } - err = wrapCPUProfile(viper, logger, func() error { - return opts.StartCommandHandler(viper, logger, clientCtx, appCreator, withCMT, opts) + err = wrapCPUProfile(serverCtx, func() error { + return opts.StartCommandHandler(serverCtx, clientCtx, appCreator, withCMT, opts) }) - logger.Debug("received quit signal") + serverCtx.Logger.Debug("received quit signal") graceDuration, _ := cmd.Flags().GetDuration(FlagShutdownGrace) if graceDuration > 0 { - logger.Info("graceful shutdown start", FlagShutdownGrace, graceDuration) + serverCtx.Logger.Info("graceful shutdown start", FlagShutdownGrace, graceDuration) <-time.After(graceDuration) - logger.Info("graceful shutdown complete") + serverCtx.Logger.Info("graceful shutdown complete") } return err @@ -216,13 +213,13 @@ is performed. Note, when enabled, gRPC will also be automatically enabled. return cmd } -func start[T types.Application](viper *viper.Viper, logger log.Logger, clientCtx client.Context, appCreator types.AppCreator[T], withCmt bool, opts StartCmdOptions[T]) error { - svrCfg, err := getAndValidateConfig(viper) +func start[T types.Application](svrCtx *Context, clientCtx client.Context, appCreator types.AppCreator[T], withCmt bool, opts StartCmdOptions[T]) error { + svrCfg, err := getAndValidateConfig(svrCtx) if err != nil { return err } - app, appCleanupFn, err := startApp[T](viper, logger, appCreator, opts) + app, appCleanupFn, err := startApp[T](svrCtx, appCreator, opts) if err != nil { return err } @@ -236,14 +233,14 @@ func start[T types.Application](viper *viper.Viper, logger log.Logger, clientCtx emitServerInfoMetrics() if !withCmt { - return startStandAlone[T](viper, logger, svrCfg, clientCtx, app, metrics, opts) + return startStandAlone[T](svrCtx, svrCfg, clientCtx, app, metrics, opts) } - return startInProcess[T](viper, logger, svrCfg, clientCtx, app, metrics, opts) + return startInProcess[T](svrCtx, svrCfg, clientCtx, app, metrics, opts) } -func startStandAlone[T types.Application](viper *viper.Viper, logger log.Logger, svrCfg serverconfig.Config, clientCtx client.Context, app T, metrics *telemetry.Metrics, opts StartCmdOptions[T]) error { - addr := viper.GetString(flagAddress) - transport := viper.GetString(flagTransport) +func startStandAlone[T types.Application](svrCtx *Context, svrCfg serverconfig.Config, clientCtx client.Context, app T, metrics *telemetry.Metrics, opts StartCmdOptions[T]) error { + addr := svrCtx.Viper.GetString(flagAddress) + transport := svrCtx.Viper.GetString(flagTransport) cmtApp := NewCometABCIWrapper(app) svr, err := server.NewServer(addr, transport, cmtApp) @@ -251,11 +248,9 @@ func startStandAlone[T types.Application](viper *viper.Viper, logger log.Logger, return fmt.Errorf("error creating listener: %w", err) } - svr.SetLogger(servercmtlog.CometLoggerWrapper{Logger: logger.With("module", "abci-server")}) - - g, ctx := getCtx(logger, false) + svr.SetLogger(servercmtlog.CometLoggerWrapper{Logger: svrCtx.Logger.With("module", "abci-server")}) - config := client.GetConfigFromViper(viper) + g, ctx := getCtx(svrCtx, false) // 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 @@ -263,7 +258,7 @@ func startStandAlone[T types.Application](viper *viper.Viper, logger log.Logger, if svrCfg.API.Enable || svrCfg.GRPC.Enable { // create tendermint client // assumes the rpc listen address is where tendermint has its rpc server - rpcclient, err := rpchttp.New(config.RPC.ListenAddress) + rpcclient, err := rpchttp.New(svrCtx.Config.RPC.ListenAddress) if err != nil { return err } @@ -277,54 +272,53 @@ func startStandAlone[T types.Application](viper *viper.Viper, logger log.Logger, app.RegisterNodeService(clientCtx, svrCfg) } - grpcSrv, clientCtx, err := startGrpcServer(ctx, g, svrCfg.GRPC, clientCtx, viper, logger, app) + grpcSrv, clientCtx, err := startGrpcServer(ctx, g, svrCfg.GRPC, clientCtx, svrCtx, app) if err != nil { return err } - err = startAPIServer(ctx, g, svrCfg, clientCtx, viper, logger, app, config.RootDir, grpcSrv, metrics) + err = startAPIServer(ctx, g, svrCfg, clientCtx, svrCtx, app, svrCtx.Config.RootDir, grpcSrv, metrics) if err != nil { return err } if opts.PostSetupStandalone != nil { - if err := opts.PostSetupStandalone(app, viper, logger, clientCtx, ctx, g); err != nil { + if err := opts.PostSetupStandalone(app, svrCtx, clientCtx, ctx, g); err != nil { return err } } g.Go(func() error { if err := svr.Start(); err != nil { - logger.Error("failed to start out-of-process ABCI server", "err", err) + svrCtx.Logger.Error("failed to start out-of-process ABCI server", "err", err) return err } // Wait for the calling process to be canceled or close the provided context, // so we can gracefully stop the ABCI server. <-ctx.Done() - logger.Info("stopping the ABCI server...") + svrCtx.Logger.Info("stopping the ABCI server...") return svr.Stop() }) return g.Wait() } -func startInProcess[T types.Application](viper *viper.Viper, logger log.Logger, svrCfg serverconfig.Config, clientCtx client.Context, app T, +func startInProcess[T types.Application](svrCtx *Context, svrCfg serverconfig.Config, clientCtx client.Context, app T, metrics *telemetry.Metrics, opts StartCmdOptions[T], ) error { - cmtCfg := client.GetConfigFromViper(viper) - - gRPCOnly := viper.GetBool(flagGRPCOnly) + cmtCfg := svrCtx.Config + gRPCOnly := svrCtx.Viper.GetBool(flagGRPCOnly) - g, ctx := getCtx(logger, true) + g, ctx := getCtx(svrCtx, true) if gRPCOnly { // TODO: Generalize logic so that gRPC only is really in startStandAlone - logger.Info("starting node in gRPC only mode; CometBFT is disabled") + svrCtx.Logger.Info("starting node in gRPC only mode; CometBFT is disabled") svrCfg.GRPC.Enable = true } else { - logger.Info("starting node with ABCI CometBFT in-process") - tmNode, cleanupFn, err := startCmtNode(ctx, cmtCfg, app, viper, logger) + svrCtx.Logger.Info("starting node with ABCI CometBFT in-process") + tmNode, cleanupFn, err := startCmtNode(ctx, cmtCfg, app, svrCtx) if err != nil { return err } @@ -344,18 +338,18 @@ func startInProcess[T types.Application](viper *viper.Viper, logger log.Logger, } } - grpcSrv, clientCtx, err := startGrpcServer(ctx, g, svrCfg.GRPC, clientCtx, viper, logger, app) + grpcSrv, clientCtx, err := startGrpcServer(ctx, g, svrCfg.GRPC, clientCtx, svrCtx, app) if err != nil { return err } - err = startAPIServer(ctx, g, svrCfg, clientCtx, viper, logger, app, cmtCfg.RootDir, grpcSrv, metrics) + err = startAPIServer(ctx, g, svrCfg, clientCtx, svrCtx, app, cmtCfg.RootDir, grpcSrv, metrics) if err != nil { return err } if opts.PostSetup != nil { - if err := opts.PostSetup(app, viper, logger, clientCtx, ctx, g); err != nil { + if err := opts.PostSetup(app, svrCtx, clientCtx, ctx, g); err != nil { return err } } @@ -370,7 +364,7 @@ func startCmtNode( ctx context.Context, cfg *cmtcfg.Config, app types.Application, - viper *viper.Viper, logger log.Logger, + svrCtx *Context, ) (tmNode *node.Node, cleanupFn func(), err error) { nodeKey, err := p2p.LoadOrGenNodeKey(cfg.NodeKeyFile()) if err != nil { @@ -387,7 +381,7 @@ func startCmtNode( getGenDocProvider(cfg), cmtcfg.DefaultDBProvider, node.DefaultMetricsProvider(cfg.Instrumentation), - servercmtlog.CometLoggerWrapper{Logger: logger}, + servercmtlog.CometLoggerWrapper{Logger: svrCtx.Logger}, ) if err != nil { return tmNode, cleanupFn, err @@ -406,8 +400,8 @@ func startCmtNode( return tmNode, cleanupFn, nil } -func getAndValidateConfig(viper *viper.Viper) (serverconfig.Config, error) { - config, err := serverconfig.GetConfig(viper) +func getAndValidateConfig(svrCtx *Context) (serverconfig.Config, error) { + config, err := serverconfig.GetConfig(svrCtx.Viper) if err != nil { return config, err } @@ -483,7 +477,7 @@ func startGrpcServer( g *errgroup.Group, config serverconfig.GRPCConfig, clientCtx client.Context, - viper *viper.Viper, logger log.Logger, + svrCtx *Context, app types.Application, ) (*grpc.Server, client.Context, error) { if !config.Enable { @@ -520,7 +514,7 @@ func startGrpcServer( } clientCtx = clientCtx.WithGRPCClient(grpcClient) - logger.Debug("gRPC client assigned to client context", "target", config.Address) + svrCtx.Logger.Debug("gRPC client assigned to client context", "target", config.Address) grpcSrv, err := servergrpc.NewGRPCServer(clientCtx, app, config) if err != nil { @@ -530,7 +524,7 @@ func startGrpcServer( // Start the gRPC server in a goroutine. Note, the provided ctx will ensure // that the server is gracefully shut down. g.Go(func() error { - return servergrpc.StartGRPCServer(ctx, logger.With("module", "grpc-server"), config, grpcSrv) + return servergrpc.StartGRPCServer(ctx, svrCtx.Logger.With("module", "grpc-server"), config, grpcSrv) }) return grpcSrv, clientCtx, nil } @@ -540,7 +534,7 @@ func startAPIServer( g *errgroup.Group, svrCfg serverconfig.Config, clientCtx client.Context, - viper *viper.Viper, logger log.Logger, + svrCtx *Context, app types.Application, home string, grpcSrv *grpc.Server, @@ -552,7 +546,7 @@ func startAPIServer( clientCtx = clientCtx.WithHomeDir(home) - apiSrv := api.New(clientCtx, logger.With("module", "api-server"), grpcSrv) + apiSrv := api.New(clientCtx, svrCtx.Logger.With("module", "api-server"), grpcSrv) app.RegisterAPIRoutes(apiSrv, svrCfg.API) if svrCfg.Telemetry.Enabled { @@ -574,25 +568,25 @@ func startTelemetry(cfg serverconfig.Config) (*telemetry.Metrics, error) { // return. // // NOTE: We expect the caller to handle graceful shutdown and signal handling. -func wrapCPUProfile(viper *viper.Viper, logger log.Logger, callbackFn func() error) error { - if cpuProfile := viper.GetString(flagCPUProfile); cpuProfile != "" { +func wrapCPUProfile(svrCtx *Context, callbackFn func() error) error { + if cpuProfile := svrCtx.Viper.GetString(flagCPUProfile); cpuProfile != "" { f, err := os.Create(cpuProfile) if err != nil { return err } - logger.Info("starting CPU profiler", "profile", cpuProfile) + svrCtx.Logger.Info("starting CPU profiler", "profile", cpuProfile) if err := pprof.StartCPUProfile(f); err != nil { return err } defer func() { - logger.Info("stopping CPU profiler", "profile", cpuProfile) + svrCtx.Logger.Info("stopping CPU profiler", "profile", cpuProfile) pprof.StopCPUProfile() if err := f.Close(); err != nil { - logger.Info("failed to close cpu-profile file", "profile", cpuProfile, "err", err.Error()) + svrCtx.Logger.Info("failed to close cpu-profile file", "profile", cpuProfile, "err", err.Error()) } }() } @@ -619,43 +613,41 @@ func emitServerInfoMetrics() { telemetry.SetGaugeWithLabels([]string{"server", "info"}, 1, ls) } -func getCtx(logger log.Logger, block bool) (*errgroup.Group, context.Context) { +func getCtx(svrCtx *Context, block bool) (*errgroup.Group, context.Context) { ctx, cancelFn := context.WithCancel(context.Background()) g, ctx := errgroup.WithContext(ctx) // listen for quit signals so the calling parent process can gracefully exit - ListenForQuitSignals(g, block, cancelFn, logger) + ListenForQuitSignals(g, block, cancelFn, svrCtx.Logger) return g, ctx } -func startApp[T types.Application](viper *viper.Viper, logger log.Logger, appCreator types.AppCreator[T], opts StartCmdOptions[T]) (app T, cleanupFn func(), err error) { - traceWriter, traceCleanupFn, err := SetupTraceWriter(logger, viper.GetString(flagTraceStore)) +func startApp[T types.Application](svrCtx *Context, appCreator types.AppCreator[T], opts StartCmdOptions[T]) (app T, cleanupFn func(), err error) { + traceWriter, traceCleanupFn, err := SetupTraceWriter(svrCtx.Logger, svrCtx.Viper.GetString(flagTraceStore)) if err != nil { return app, traceCleanupFn, err } - cmtCfg := client.GetConfigFromViper(viper) - - home := cmtCfg.RootDir - db, err := opts.DBOpener(home, GetAppDBBackend(viper)) + home := svrCtx.Config.RootDir + db, err := opts.DBOpener(home, GetAppDBBackend(svrCtx.Viper)) if err != nil { return app, traceCleanupFn, err } - if isTestnet, ok := viper.Get(KeyIsTestnet).(bool); ok && isTestnet { + if isTestnet, ok := svrCtx.Viper.Get(KeyIsTestnet).(bool); ok && isTestnet { var appPtr *T - appPtr, err = testnetify[T](viper, logger, appCreator, db, traceWriter) + appPtr, err = testnetify[T](svrCtx, appCreator, db, traceWriter) if err != nil { return app, traceCleanupFn, err } app = *appPtr } else { - app = appCreator(logger, db, traceWriter, viper) + app = appCreator(svrCtx.Logger, db, traceWriter, svrCtx.Viper) } cleanupFn = func() { traceCleanupFn() if localErr := app.Close(); localErr != nil { - logger.Error(localErr.Error()) + svrCtx.Logger.Error(localErr.Error()) } } return app, cleanupFn, nil @@ -698,10 +690,8 @@ you want to test the upgrade handler itself. Example: "in-place-testnet localosmosis osmo12smx2wdlyttvyzvzg54y2vnqwq2qjateuf7thj", Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { - viper := client.GetViperFromCmd(cmd) - logger := client.GetLoggerFromCmd(cmd) - - _, err := GetPruningOptionsFromFlags(viper) + serverCtx := GetServerContextFromCmd(cmd) + _, err := GetPruningOptionsFromFlags(serverCtx.Viper) if err != nil { return err } @@ -713,7 +703,7 @@ you want to test the upgrade handler itself. withCMT, _ := cmd.Flags().GetBool(flagWithComet) if !withCMT { - logger.Info("starting ABCI without CometBFT") + serverCtx.Logger.Info("starting ABCI without CometBFT") } newChainID := args[0] @@ -735,20 +725,20 @@ you want to test the upgrade handler itself. // Set testnet keys to be used by the application. // This is done to prevent changes to existing start API. - viper.Set(KeyIsTestnet, true) - viper.Set(KeyNewChainID, newChainID) - viper.Set(KeyNewOpAddr, newOperatorAddress) + serverCtx.Viper.Set(KeyIsTestnet, true) + serverCtx.Viper.Set(KeyNewChainID, newChainID) + serverCtx.Viper.Set(KeyNewOpAddr, newOperatorAddress) - err = wrapCPUProfile(viper, logger, func() error { - return opts.StartCommandHandler(viper, logger, clientCtx, testnetAppCreator, withCMT, opts) + err = wrapCPUProfile(serverCtx, func() error { + return opts.StartCommandHandler(serverCtx, clientCtx, testnetAppCreator, withCMT, opts) }) - logger.Debug("received quit signal") + serverCtx.Logger.Debug("received quit signal") graceDuration, _ := cmd.Flags().GetDuration(FlagShutdownGrace) if graceDuration > 0 { - logger.Info("graceful shutdown start", FlagShutdownGrace, graceDuration) + serverCtx.Logger.Info("graceful shutdown start", FlagShutdownGrace, graceDuration) <-time.After(graceDuration) - logger.Info("graceful shutdown complete") + serverCtx.Logger.Info("graceful shutdown complete") } return err @@ -763,10 +753,10 @@ you want to test the upgrade handler itself. // testnetify modifies both state and blockStore, allowing the provided operator address and local validator key to control the network // that the state in the data folder represents. The chainID of the local genesis file is modified to match the provided chainID. -func testnetify[T types.Application](viper *viper.Viper, logger log.Logger, testnetAppCreator types.AppCreator[T], db dbm.DB, traceWriter io.WriteCloser) (*T, error) { - config := client.GetConfigFromViper(viper) +func testnetify[T types.Application](ctx *Context, testnetAppCreator types.AppCreator[T], db dbm.DB, traceWriter io.WriteCloser) (*T, error) { + config := ctx.Config - newChainID, ok := viper.Get(KeyNewChainID).(string) + newChainID, ok := ctx.Viper.Get(KeyNewChainID).(string) if !ok { return nil, fmt.Errorf("expected string for key %s", KeyNewChainID) } @@ -819,25 +809,25 @@ func testnetify[T types.Application](viper *viper.Viper, logger log.Logger, test return nil, err } - viper.Set(KeyNewValAddr, validatorAddress) - viper.Set(KeyUserPubKey, userPubKey) - testnetApp := testnetAppCreator(logger, db, traceWriter, viper) + ctx.Viper.Set(KeyNewValAddr, validatorAddress) + ctx.Viper.Set(KeyUserPubKey, userPubKey) + testnetApp := testnetAppCreator(ctx.Logger, db, traceWriter, ctx.Viper) // We need to create a temporary proxyApp to get the initial state of the application. // Depending on how the node was stopped, the application height can differ from the blockStore height. // This height difference changes how we go about modifying the state. cmtApp := NewCometABCIWrapper(testnetApp) - _, context := getCtx(logger, true) + _, context := getCtx(ctx, true) clientCreator := proxy.NewLocalClientCreator(cmtApp) metrics := node.DefaultMetricsProvider(cmtcfg.DefaultConfig().Instrumentation) _, _, _, _, _, proxyMetrics, _, _ := metrics(genDoc.ChainID) // nolint: dogsled // function from comet proxyApp := proxy.NewAppConns(clientCreator, proxyMetrics) if err := proxyApp.Start(); err != nil { - return nil, fmt.Errorf("error starting proxy app connections: %w", err) + return nil, fmt.Errorf("error starting proxy app connections: %v", err) } res, err := proxyApp.Query().Info(context, proxy.InfoRequest) if err != nil { - return nil, fmt.Errorf("error calling Info: %w", err) + return nil, fmt.Errorf("error calling Info: %v", err) } err = proxyApp.Stop() if err != nil { diff --git a/server/util.go b/server/util.go index 493d0a5daaa8..2722bc458390 100644 --- a/server/util.go +++ b/server/util.go @@ -24,28 +24,45 @@ import ( "github.com/spf13/viper" "golang.org/x/sync/errgroup" - corectx "cosmossdk.io/core/context" "cosmossdk.io/log" + corectx "cosmossdk.io/core/context" "cosmossdk.io/store" "cosmossdk.io/store/snapshots" snapshottypes "cosmossdk.io/store/snapshots/types" storetypes "cosmossdk.io/store/types" "github.com/cosmos/cosmos-sdk/baseapp" - "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/server/config" "github.com/cosmos/cosmos-sdk/server/types" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/mempool" "github.com/cosmos/cosmos-sdk/version" genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" ) -// Deprecated: Do not use, we use viper to track all config +// ServerContextKey defines the context key used to retrieve a server.Context from +// a command's Context. +const ServerContextKey = sdk.ContextKey("server.context") + +// Context server context +// Deprecated: Do not use since we use viper to track all config type Context struct { Viper *viper.Viper - Logger log.Logger Config *cmtcfg.Config + Logger log.Logger +} + +func NewDefaultContext() *Context { + return NewContext( + viper.New(), + cmtcfg.DefaultConfig(), + log.NewLogger(os.Stdout), + ) +} + +func NewContext(v *viper.Viper, config *cmtcfg.Config, logger log.Logger) *Context { + return &Context{v, config, logger} } func bindFlags(basename string, cmd *cobra.Command, v *viper.Viper) (err error) { @@ -85,19 +102,20 @@ func bindFlags(basename string, cmd *cobra.Command, v *viper.Viper) (err error) // InterceptConfigsPreRunHandler is identical to InterceptConfigsAndCreateContext // except it also sets the server context on the command and the server logger. func InterceptConfigsPreRunHandler(cmd *cobra.Command, customAppConfigTemplate string, customAppConfig interface{}, cmtConfig *cmtcfg.Config) error { - viper, err := InterceptConfigsAndCreateContext(cmd, customAppConfigTemplate, customAppConfig, cmtConfig) + serverCtx, err := InterceptConfigsAndCreateContext(cmd, customAppConfigTemplate, customAppConfig, cmtConfig) if err != nil { return err } // overwrite default server logger - logger, err := CreateSDKLogger(viper, cmd.OutOrStdout()) + logger, err := CreateSDKLogger(serverCtx, cmd.OutOrStdout()) if err != nil { return err } + serverCtx.Logger = logger.With(log.ModuleKey, "server") // set server context - return SetCmdServerContext(cmd, viper, logger) + return SetCmdServerContext(cmd, serverCtx) } // InterceptConfigsAndCreateContext performs a pre-run function for the root daemon @@ -110,8 +128,8 @@ func InterceptConfigsPreRunHandler(cmd *cobra.Command, customAppConfigTemplate s // is used to read and parse the application configuration. Command handlers can // fetch the server Context to get the CometBFT configuration or to get access // to Viper. -func InterceptConfigsAndCreateContext(cmd *cobra.Command, customAppConfigTemplate string, customAppConfig interface{}, cmtConfig *cmtcfg.Config) (*viper.Viper, error) { - v := viper.New() +func InterceptConfigsAndCreateContext(cmd *cobra.Command, customAppConfigTemplate string, customAppConfig interface{}, cmtConfig *cmtcfg.Config) (*Context, error) { + serverCtx := NewDefaultContext() // Get the executable name and configure the viper instance so that environmental // variables are checked based off that name. The underscore character is used @@ -124,44 +142,46 @@ func InterceptConfigsAndCreateContext(cmd *cobra.Command, customAppConfigTemplat basename := path.Base(executableName) // configure the viper instance - if err := v.BindPFlags(cmd.Flags()); err != nil { + if err := serverCtx.Viper.BindPFlags(cmd.Flags()); err != nil { return nil, err } - if err := v.BindPFlags(cmd.PersistentFlags()); err != nil { + if err := serverCtx.Viper.BindPFlags(cmd.PersistentFlags()); err != nil { return nil, err } - v.SetEnvPrefix(basename) - v.SetEnvKeyReplacer(strings.NewReplacer(".", "_", "-", "_")) - v.AutomaticEnv() + serverCtx.Viper.SetEnvPrefix(basename) + serverCtx.Viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_", "-", "_")) + serverCtx.Viper.AutomaticEnv() // intercept configuration files, using both Viper instances separately - err = interceptConfigs(v, customAppConfigTemplate, customAppConfig, cmtConfig) + config, err := interceptConfigs(serverCtx.Viper, customAppConfigTemplate, customAppConfig, cmtConfig) if err != nil { return nil, err } - if err = bindFlags(basename, cmd, v); err != nil { + // return value is a CometBFT configuration object + serverCtx.Config = config + if err = bindFlags(basename, cmd, serverCtx.Viper); err != nil { return nil, err } - return v, nil + return serverCtx, nil } // CreateSDKLogger creates a the default SDK logger. // It reads the log level and format from the server context. -func CreateSDKLogger(v *viper.Viper, out io.Writer) (log.Logger, error) { +func CreateSDKLogger(ctx *Context, out io.Writer) (log.Logger, error) { var opts []log.Option - if v.GetString(flags.FlagLogFormat) == flags.OutputFormatJSON { + if ctx.Viper.GetString(flags.FlagLogFormat) == flags.OutputFormatJSON { opts = append(opts, log.OutputJSONOption()) } opts = append(opts, - log.ColorOption(!v.GetBool(flags.FlagLogNoColor)), + log.ColorOption(!ctx.Viper.GetBool(flags.FlagLogNoColor)), // We use CometBFT flag (cmtcli.TraceFlag) for trace logging. - log.TraceOption(v.GetBool(FlagTrace))) + log.TraceOption(ctx.Viper.GetBool(FlagTrace))) // check and set filter level or keys for the logger if any - logLvlStr := v.GetString(flags.FlagLogLevel) + logLvlStr := ctx.Viper.GetString(flags.FlagLogLevel) if logLvlStr == "" { return log.NewLogger(out, opts...), nil } @@ -186,29 +206,17 @@ func CreateSDKLogger(v *viper.Viper, out io.Writer) (log.Logger, error) { // GetServerContextFromCmd returns a Context from a command or an empty Context // if it has not been set. func GetServerContextFromCmd(cmd *cobra.Command) *Context { - serverCtx := &Context{} - if v := cmd.Context().Value(corectx.ViperContextKey{}); v != nil { - viper := v.(*viper.Viper) - serverCtx.Viper = viper - serverCtx.Config = client.GetConfigFromViper(viper) - } else { - serverCtx.Viper = viper.New() - serverCtx.Config = cmtcfg.DefaultConfig() + if v := cmd.Context().Value(ServerContextKey); v != nil { + serverCtxPtr := v.(*Context) + return serverCtxPtr } - if v := cmd.Context().Value(corectx.LoggerContextKey{}); v != nil { - logger := v.(log.Logger) - serverCtx.Logger = logger - } else { - serverCtx.Logger = log.NewLogger(cmd.OutOrStdout()) - } - - return serverCtx + return NewDefaultContext() } // SetCmdServerContext sets a command's Context value to the provided argument. // If the context has not been set, set the given context as the default. -func SetCmdServerContext(cmd *cobra.Command, viper *viper.Viper, logger log.Logger) error { +func SetCmdServerContext(cmd *cobra.Command, serverCtx *Context) error { var cmdCtx context.Context if cmd.Context() == nil { @@ -217,8 +225,13 @@ func SetCmdServerContext(cmd *cobra.Command, viper *viper.Viper, logger log.Logg cmdCtx = cmd.Context() } - cmd.SetContext(context.WithValue(cmdCtx, corectx.LoggerContextKey{}, logger)) - cmd.SetContext(context.WithValue(cmdCtx, corectx.ViperContextKey{}, viper)) + cmdCtx = context.WithValue(cmdCtx, ServerContextKey, serverCtx) + cmdCtx = context.WithValue(cmdCtx, corectx.ViperContextKey{}, serverCtx.Viper) + cmdCtx = context.WithValue(cmdCtx, corectx.LoggerContextKey{}, serverCtx.Logger) + + cmd.SetContext(cmdCtx) + + fmt.Println("After set", serverCtx.Viper.GetString(flags.FlagHome)) return nil } @@ -228,8 +241,9 @@ func SetCmdServerContext(cmd *cobra.Command, viper *viper.Viper, logger log.Logg // configuration file. The CometBFT configuration file is parsed given a root // Viper object, whereas the application is parsed with the private package-aware // viperCfg object. -func interceptConfigs(rootViper *viper.Viper, customAppTemplate string, customConfig interface{}, cmtConfig *cmtcfg.Config) error { +func interceptConfigs(rootViper *viper.Viper, customAppTemplate string, customConfig interface{}, cmtConfig *cmtcfg.Config) (*cmtcfg.Config, error) { rootDir := rootViper.GetString(flags.FlagHome) + fmt.Println("Init root", rootDir) configPath := filepath.Join(rootDir, "config") cmtCfgFile := filepath.Join(configPath, "config.toml") @@ -240,7 +254,7 @@ func interceptConfigs(rootViper *viper.Viper, customAppTemplate string, customCo cmtcfg.EnsureRoot(rootDir) if err = conf.ValidateBasic(); err != nil { - return fmt.Errorf("error in config file: %w", err) + return nil, fmt.Errorf("error in config file: %w", err) } defaultCometCfg := cmtcfg.DefaultConfig() @@ -256,7 +270,7 @@ func interceptConfigs(rootViper *viper.Viper, customAppTemplate string, customCo cmtcfg.WriteConfigFile(cmtCfgFile, conf) case err != nil: - return err + return nil, err default: rootViper.SetConfigType("toml") @@ -264,7 +278,7 @@ func interceptConfigs(rootViper *viper.Viper, customAppTemplate string, customCo rootViper.AddConfigPath(configPath) if err := rootViper.ReadInConfig(); err != nil { - return fmt.Errorf("failed to read in %s: %w", cmtCfgFile, err) + return nil, fmt.Errorf("failed to read in %s: %w", cmtCfgFile, err) } } @@ -272,35 +286,37 @@ func interceptConfigs(rootViper *viper.Viper, customAppTemplate string, customCo // This may come from the configuration file above but also any of the other // sources viper uses. if err := rootViper.Unmarshal(conf); err != nil { - return err + return nil, err } + conf.SetRoot(rootDir) + appCfgFilePath := filepath.Join(configPath, "app.toml") if _, err := os.Stat(appCfgFilePath); os.IsNotExist(err) { if (customAppTemplate != "" && customConfig == nil) || (customAppTemplate == "" && customConfig != nil) { - return fmt.Errorf("customAppTemplate and customConfig should be both nil or not nil") + return nil, fmt.Errorf("customAppTemplate and customConfig should be both nil or not nil") } if customAppTemplate != "" { if err := config.SetConfigTemplate(customAppTemplate); err != nil { - return fmt.Errorf("failed to set config template: %w", err) + return nil, fmt.Errorf("failed to set config template: %w", err) } if err = rootViper.Unmarshal(&customConfig); err != nil { - return fmt.Errorf("failed to parse %s: %w", appCfgFilePath, err) + return nil, fmt.Errorf("failed to parse %s: %w", appCfgFilePath, err) } if err := config.WriteConfigFile(appCfgFilePath, customConfig); err != nil { - return fmt.Errorf("failed to write %s: %w", appCfgFilePath, err) + return nil, fmt.Errorf("failed to write %s: %w", appCfgFilePath, err) } } else { appConf, err := config.ParseConfig(rootViper) if err != nil { - return fmt.Errorf("failed to parse %s: %w", appCfgFilePath, err) + return nil, fmt.Errorf("failed to parse %s: %w", appCfgFilePath, err) } if err := config.WriteConfigFile(appCfgFilePath, appConf); err != nil { - return fmt.Errorf("failed to write %s: %w", appCfgFilePath, err) + return nil, fmt.Errorf("failed to write %s: %w", appCfgFilePath, err) } } } @@ -310,10 +326,10 @@ func interceptConfigs(rootViper *viper.Viper, customAppTemplate string, customCo rootViper.AddConfigPath(configPath) if err := rootViper.MergeInConfig(); err != nil { - return fmt.Errorf("failed to merge configuration: %w", err) + return nil, fmt.Errorf("failed to merge configuration: %w", err) } - return nil + return conf, nil } // AddCommands add server commands diff --git a/server/util_test.go b/server/util_test.go index 040bb6415a9b..11f5cbb208c9 100644 --- a/server/util_test.go +++ b/server/util_test.go @@ -16,9 +16,6 @@ import ( "github.com/spf13/viper" "github.com/stretchr/testify/require" - corectx "cosmossdk.io/core/context" - "cosmossdk.io/log" - "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" codectestutil "github.com/cosmos/cosmos-sdk/codec/testutil" @@ -62,13 +59,13 @@ func TestInterceptConfigsPreRunHandlerCreatesConfigFilesWhenMissing(t *testing.T cmd.PreRunE = preRunETestImpl - ctx := context.WithValue(context.Background(), corectx.LoggerContextKey{}, log.NewLogger(os.Stdout)) - ctx = context.WithValue(ctx, corectx.ViperContextKey{}, viper.New()) + serverCtx := &server.Context{} + ctx := context.WithValue(context.Background(), server.ServerContextKey, serverCtx) if err := cmd.ExecuteContext(ctx); !errors.Is(err, errCanceledInPreRun) { t.Fatalf("function failed with [%T] %v", err, err) } - config := client.GetConfigFromCmd(cmd) + serverCtx = server.GetServerContextFromCmd(cmd) // Test that config.toml is created configTomlPath := path.Join(tempDir, "config", "config.toml") @@ -86,7 +83,7 @@ func TestInterceptConfigsPreRunHandlerCreatesConfigFilesWhenMissing(t *testing.T } // Test that CometBFT config is initialized - if config == nil { + if serverCtx.Config == nil { t.Fatal("CometBFT config not created") } @@ -106,10 +103,7 @@ func TestInterceptConfigsPreRunHandlerCreatesConfigFilesWhenMissing(t *testing.T } // Test that the config for use in server/start.go is created - v := ctx.Value(corectx.ViperContextKey{}) - viper, _ := v.(*viper.Viper) - - if viper == nil { + if serverCtx.Viper == nil { t.Error("app config Viper instance not created") } } @@ -144,16 +138,16 @@ func TestInterceptConfigsPreRunHandlerReadsConfigToml(t *testing.T) { cmd.PreRunE = preRunETestImpl - ctx := context.WithValue(context.Background(), corectx.LoggerContextKey{}, log.NewLogger(os.Stdout)) - ctx = context.WithValue(ctx, corectx.ViperContextKey{}, viper.New()) + serverCtx := &server.Context{} + ctx := context.WithValue(context.Background(), server.ServerContextKey, serverCtx) if err := cmd.ExecuteContext(ctx); !errors.Is(err, errCanceledInPreRun) { t.Fatalf("function failed with [%T] %v", err, err) } - config := client.GetConfigFromCmd(cmd) + serverCtx = server.GetServerContextFromCmd(cmd) - if testDbBackend != config.DBBackend { + if testDbBackend != serverCtx.Config.DBBackend { t.Error("backend was not set from config.toml") } } @@ -184,16 +178,16 @@ func TestInterceptConfigsPreRunHandlerReadsAppToml(t *testing.T) { cmd.PreRunE = preRunETestImpl - ctx := context.WithValue(context.Background(), corectx.LoggerContextKey{}, log.NewLogger(os.Stdout)) - ctx = context.WithValue(ctx, corectx.ViperContextKey{}, viper.New()) + serverCtx := &server.Context{} + ctx := context.WithValue(context.Background(), server.ServerContextKey, serverCtx) if err := cmd.ExecuteContext(ctx); !errors.Is(err, errCanceledInPreRun) { t.Fatalf("function failed with [%T] %v", err, err) } - viper := client.GetViperFromCmd(cmd) + serverCtx = server.GetServerContextFromCmd(cmd) - if testHaltTime != viper.GetInt("halt-time") { + if testHaltTime != serverCtx.Viper.GetInt("halt-time") { t.Error("Halt time was not set from app.toml") } } @@ -214,16 +208,16 @@ func TestInterceptConfigsPreRunHandlerReadsFlags(t *testing.T) { cmd.PreRunE = preRunETestImpl - ctx := context.WithValue(context.Background(), corectx.LoggerContextKey{}, log.NewLogger(os.Stdout)) - ctx = context.WithValue(ctx, corectx.ViperContextKey{}, viper.New()) + serverCtx := &server.Context{} + ctx := context.WithValue(context.Background(), server.ServerContextKey, serverCtx) if err := cmd.ExecuteContext(ctx); !errors.Is(err, errCanceledInPreRun) { t.Fatalf("function failed with [%T] %v", err, err) } - config := client.GetConfigFromCmd(cmd) + serverCtx = server.GetServerContextFromCmd(cmd) - if testAddr != config.RPC.ListenAddress { + if testAddr != serverCtx.Config.RPC.ListenAddress { t.Error("RPCListenAddress was not set from command flags") } } @@ -252,16 +246,16 @@ func TestInterceptConfigsPreRunHandlerReadsEnvVars(t *testing.T) { cmd.PreRunE = preRunETestImpl - ctx := context.WithValue(context.Background(), corectx.LoggerContextKey{}, log.NewLogger(os.Stdout)) - ctx = context.WithValue(ctx, corectx.ViperContextKey{}, viper.New()) + serverCtx := &server.Context{} + ctx := context.WithValue(context.Background(), server.ServerContextKey, serverCtx) if err := cmd.ExecuteContext(ctx); !errors.Is(err, errCanceledInPreRun) { t.Fatalf("function failed with [%T] %v", err, err) } - config := client.GetConfigFromCmd(cmd) + serverCtx = server.GetServerContextFromCmd(cmd) - if testAddr != config.RPC.ListenAddress { + if testAddr != serverCtx.Config.RPC.ListenAddress { t.Errorf("RPCListenAddress was not set from env. var. %q", envVarName) } } @@ -361,16 +355,16 @@ func TestInterceptConfigsPreRunHandlerPrecedenceFlag(t *testing.T) { testCommon := newPrecedenceCommon(t) testCommon.setAll(t, &TestAddrExpected, &TestAddrNotExpected, &TestAddrNotExpected) - ctx := context.WithValue(context.Background(), corectx.LoggerContextKey{}, log.NewLogger(os.Stdout)) - ctx = context.WithValue(ctx, corectx.ViperContextKey{}, viper.New()) + serverCtx := &server.Context{} + ctx := context.WithValue(context.Background(), server.ServerContextKey, serverCtx) if err := testCommon.cmd.ExecuteContext(ctx); !errors.Is(err, errCanceledInPreRun) { t.Fatalf("function failed with [%T] %v", err, err) } - config := client.GetConfigFromCmd(testCommon.cmd) + serverCtx = server.GetServerContextFromCmd(testCommon.cmd) - if TestAddrExpected != config.RPC.ListenAddress { + if TestAddrExpected != serverCtx.Config.RPC.ListenAddress { t.Fatalf("RPCListenAddress was not set from flag %q", testCommon.flagName) } } @@ -379,16 +373,16 @@ func TestInterceptConfigsPreRunHandlerPrecedenceEnvVar(t *testing.T) { testCommon := newPrecedenceCommon(t) testCommon.setAll(t, nil, &TestAddrExpected, &TestAddrNotExpected) - ctx := context.WithValue(context.Background(), corectx.LoggerContextKey{}, log.NewLogger(os.Stdout)) - ctx = context.WithValue(ctx, corectx.ViperContextKey{}, viper.New()) + serverCtx := &server.Context{} + ctx := context.WithValue(context.Background(), server.ServerContextKey, serverCtx) if err := testCommon.cmd.ExecuteContext(ctx); !errors.Is(err, errCanceledInPreRun) { t.Fatalf("function failed with [%T] %v", err, err) } - config := client.GetConfigFromCmd(testCommon.cmd) + serverCtx = server.GetServerContextFromCmd(testCommon.cmd) - if TestAddrExpected != config.RPC.ListenAddress { + if TestAddrExpected != serverCtx.Config.RPC.ListenAddress { t.Errorf("RPCListenAddress was not set from env. var. %q", testCommon.envVarName) } } @@ -397,16 +391,16 @@ func TestInterceptConfigsPreRunHandlerPrecedenceConfigFile(t *testing.T) { testCommon := newPrecedenceCommon(t) testCommon.setAll(t, nil, nil, &TestAddrExpected) - ctx := context.WithValue(context.Background(), corectx.LoggerContextKey{}, log.NewLogger(os.Stdout)) - ctx = context.WithValue(ctx, corectx.ViperContextKey{}, viper.New()) + serverCtx := &server.Context{} + ctx := context.WithValue(context.Background(), server.ServerContextKey, serverCtx) if err := testCommon.cmd.ExecuteContext(ctx); !errors.Is(err, errCanceledInPreRun) { t.Fatalf("function failed with [%T] %v", err, err) } - config := client.GetConfigFromCmd(testCommon.cmd) + serverCtx = server.GetServerContextFromCmd(testCommon.cmd) - if TestAddrExpected != config.RPC.ListenAddress { + if TestAddrExpected != serverCtx.Config.RPC.ListenAddress { t.Errorf("RPCListenAddress was not read from file %q", testCommon.configTomlPath) } } @@ -415,16 +409,16 @@ func TestInterceptConfigsPreRunHandlerPrecedenceConfigDefault(t *testing.T) { testCommon := newPrecedenceCommon(t) // Do not set anything - ctx := context.WithValue(context.Background(), corectx.LoggerContextKey{}, log.NewLogger(os.Stdout)) - ctx = context.WithValue(ctx, corectx.ViperContextKey{}, viper.New()) + serverCtx := &server.Context{} + ctx := context.WithValue(context.Background(), server.ServerContextKey, serverCtx) if err := testCommon.cmd.ExecuteContext(ctx); !errors.Is(err, errCanceledInPreRun) { t.Fatalf("function failed with [%T] %v", err, err) } - config := client.GetConfigFromCmd(testCommon.cmd) + serverCtx = server.GetServerContextFromCmd(testCommon.cmd) - if config.RPC.ListenAddress != "tcp://127.0.0.1:26657" { + if serverCtx.Config.RPC.ListenAddress != "tcp://127.0.0.1:26657" { t.Error("RPCListenAddress is not using default") } } @@ -446,9 +440,8 @@ func TestInterceptConfigsWithBadPermissions(t *testing.T) { cmd.PreRunE = preRunETestImpl - ctx := context.WithValue(context.Background(), corectx.LoggerContextKey{}, log.NewNopLogger()) - ctx = context.WithValue(ctx, corectx.ViperContextKey{}, viper.New()) - + 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) } @@ -462,10 +455,9 @@ func TestEmptyMinGasPrices(t *testing.T) { // Run InitCmd to create necessary config files. clientCtx := client.Context{}.WithHomeDir(tempDir).WithCodec(encCfg.Codec) - viper := viper.New() - viper.Set(flags.FlagHome, tempDir) - ctx := context.WithValue(context.Background(), corectx.ViperContextKey{}, viper) - ctx = context.WithValue(ctx, corectx.LoggerContextKey{}, log.NewLogger(os.Stdout)) + serverCtx := server.NewDefaultContext() + serverCtx.Config.SetRoot(tempDir) + ctx := context.WithValue(context.Background(), server.ServerContextKey, serverCtx) ctx = context.WithValue(ctx, client.ClientContextKey, &clientCtx) cmd := genutilcli.InitCmd(module.NewManager()) cmd.SetArgs([]string{"appnode-test"}) @@ -483,12 +475,12 @@ func TestEmptyMinGasPrices(t *testing.T) { cmd = server.StartCmd[servertypes.Application](nil) cmd.PersistentFlags().String(flags.FlagHome, tempDir, "") cmd.PreRunE = func(cmd *cobra.Command, _ []string) error { - viper, err := server.InterceptConfigsAndCreateContext(cmd, "", nil, cmtcfg.DefaultConfig()) + ctx, err := server.InterceptConfigsAndCreateContext(cmd, "", nil, cmtcfg.DefaultConfig()) if err != nil { return err } - return server.SetCmdServerContext(cmd, viper, client.GetLoggerFromCmd(cmd)) + return server.SetCmdServerContext(cmd, ctx) } err = cmd.ExecuteContext(ctx) require.Errorf(t, err, sdkerrors.ErrAppConfig.Error())