Merge PR #6426: Migrate API Server

This commit is contained in:
Alexander Bezobchuk 2020-06-15 13:39:09 -04:00 committed by GitHub
parent 6336f95802
commit 6a05b83069
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
29 changed files with 287 additions and 218 deletions

2
.gitattributes vendored
View File

@ -1 +1 @@
client/lcd/swagger-ui/* linguist-vendored
client/docs/swagger-ui/* linguist-vendored

View File

@ -39,6 +39,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
### Client Breaking
* (api) [\#6426](https://github.com/cosmos/cosmos-sdk/pull/6426) The ability to start an out-of-process API REST server has now been removed. Instead, the API server is now started in-process along with the application and Tendermint. Configuration options have been added to `app.toml` to enable/disable the API server along with additional HTTP server options.
* (baseapp) [\#6384](https://github.com/cosmos/cosmos-sdk/pull/6384) The `Result.Data` is now a Protocol Buffer encoded binary blob of type `TxData`. The `TxData` contains `Data` which contains a list of Protocol Buffer encoded message data and the corresponding message type.
* (x/gov) [#6295](https://github.com/cosmos/cosmos-sdk/pull/6295) Fix typo in querying governance params.
* (x/auth) [\#6054](https://github.com/cosmos/cosmos-sdk/pull/6054) Remove custom JSON marshaling for base accounts as multsigs cannot be bech32 decoded.

View File

@ -217,9 +217,9 @@ lint:
.PHONY: lint
format:
find . -name '*.go' -type f -not -path "./vendor*" -not -path "*.git*" -not -path "./client/lcd/statik/statik.go" -not -path "./tests/mocks/*" -not -name '*.pb.go' | xargs gofmt -w -s
find . -name '*.go' -type f -not -path "./vendor*" -not -path "*.git*" -not -path "./client/lcd/statik/statik.go" -not -path "./tests/mocks/*" -not -name '*.pb.go' | xargs misspell -w
find . -name '*.go' -type f -not -path "./vendor*" -not -path "*.git*" -not -path "./client/lcd/statik/statik.go" -not -path "./tests/mocks/*" -not -name '*.pb.go' | xargs goimports -w -local github.com/cosmos/cosmos-sdk
find . -name '*.go' -type f -not -path "./vendor*" -not -path "*.git*" -not -path "./client/docs/statik/statik.go" -not -path "./tests/mocks/*" -not -name '*.pb.go' | xargs gofmt -w -s
find . -name '*.go' -type f -not -path "./vendor*" -not -path "*.git*" -not -path "./client/docs/statik/statik.go" -not -path "./tests/mocks/*" -not -name '*.pb.go' | xargs misspell -w
find . -name '*.go' -type f -not -path "./vendor*" -not -path "*.git*" -not -path "./client/docs/statik/statik.go" -not -path "./tests/mocks/*" -not -name '*.pb.go' | xargs goimports -w -local github.com/cosmos/cosmos-sdk
.PHONY: format
###############################################################################

View File

@ -21,8 +21,8 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
)
// Context implements a typical context created in SDK modules for
// transaction handling and queries.
// Context implements a typical context created in SDK modules for transaction
// handling and queries.
type Context struct {
FromAddress sdk.AccAddress
Client rpcclient.Client
@ -34,10 +34,8 @@ type Context struct {
OutputFormat string
Height int64
HomeDir string
NodeURI string
From string
BroadcastMode string
Verifier tmlite.Verifier
FromName string
TrustNode bool
UseLedger bool
@ -49,6 +47,12 @@ type Context struct {
TxGenerator TxGenerator
AccountRetriever AccountRetriever
// TODO: API and CLI interfaces are migrating to a single binary (i.e be part of
// the same process of the application). We need to groom through these fields
// and remove any that no longer make sense.
NodeURI string
Verifier tmlite.Verifier
// TODO: Deprecated (remove).
Codec *codec.Codec
}
@ -267,6 +271,12 @@ func (ctx Context) WithChainID(chainID string) Context {
return ctx
}
// WithHomeDir returns a copy of the Context with HomeDir set.
func (ctx Context) WithHomeDir(dir string) Context {
ctx.HomeDir = dir
return ctx
}
// WithGenerateOnly returns a copy of the context with updated GenerateOnly value
func (ctx Context) WithGenerateOnly(generateOnly bool) Context {
ctx.GenerateOnly = generateOnly

View File

@ -1,3 +1,3 @@
package statik
//This just for fixing the error in importing empty github.com/cosmos/cosmos-sdk/client/lcd/statik
//This just for fixing the error in importing empty github.com/cosmos/cosmos-sdk/client/docs/statik

View File

Before

Width:  |  Height:  |  Size: 445 B

After

Width:  |  Height:  |  Size: 445 B

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -39,37 +39,31 @@ const (
// List of CLI flags
const (
FlagHome = tmcli.HomeFlag
FlagUseLedger = "ledger"
FlagChainID = "chain-id"
FlagNode = "node"
FlagHeight = "height"
FlagGasAdjustment = "gas-adjustment"
FlagTrustNode = "trust-node"
FlagFrom = "from"
FlagName = "name"
FlagAccountNumber = "account-number"
FlagSequence = "sequence"
FlagMemo = "memo"
FlagFees = "fees"
FlagGasPrices = "gas-prices"
FlagBroadcastMode = "broadcast-mode"
FlagDryRun = "dry-run"
FlagGenerateOnly = "generate-only"
FlagOffline = "offline"
FlagIndentResponse = "indent"
FlagListenAddr = "laddr"
FlagMaxOpenConnections = "max-open"
FlagRPCReadTimeout = "read-timeout"
FlagRPCWriteTimeout = "write-timeout"
FlagRPCMaxBodyBytes = "max-body-bytes"
FlagOutputDocument = "output-document" // inspired by wget -O
FlagSkipConfirmation = "yes"
FlagProve = "prove"
FlagKeyringBackend = "keyring-backend"
FlagPage = "page"
FlagLimit = "limit"
FlagUnsafeCORS = "unsafe-cors"
FlagHome = tmcli.HomeFlag
FlagUseLedger = "ledger"
FlagChainID = "chain-id"
FlagNode = "node"
FlagHeight = "height"
FlagGasAdjustment = "gas-adjustment"
FlagTrustNode = "trust-node"
FlagFrom = "from"
FlagName = "name"
FlagAccountNumber = "account-number"
FlagSequence = "sequence"
FlagMemo = "memo"
FlagFees = "fees"
FlagGasPrices = "gas-prices"
FlagBroadcastMode = "broadcast-mode"
FlagDryRun = "dry-run"
FlagGenerateOnly = "generate-only"
FlagOffline = "offline"
FlagIndentResponse = "indent"
FlagOutputDocument = "output-document" // inspired by wget -O
FlagSkipConfirmation = "yes"
FlagProve = "prove"
FlagKeyringBackend = "keyring-backend"
FlagPage = "page"
FlagLimit = "limit"
)
// LineBreak can be included in a command list to provide a blank line
@ -141,19 +135,6 @@ func PostCommands(cmds ...*cobra.Command) []*cobra.Command {
return cmds
}
// RegisterRestServerFlags registers the flags required for rest server
func RegisterRestServerFlags(cmd *cobra.Command) *cobra.Command {
cmd = GetCommands(cmd)[0]
cmd.Flags().String(FlagListenAddr, "tcp://localhost:1317", "The address for the server to listen on")
cmd.Flags().Uint(FlagMaxOpenConnections, 1000, "The number of maximum open connections")
cmd.Flags().Uint(FlagRPCReadTimeout, 10, "The RPC read timeout (in seconds)")
cmd.Flags().Uint(FlagRPCWriteTimeout, 10, "The RPC write timeout (in seconds)")
cmd.Flags().Uint(FlagRPCMaxBodyBytes, 1000000, "The RPC max body bytes")
cmd.Flags().Bool(FlagUnsafeCORS, false, "Allows CORS requests from all domains. For development purposes only, use it at your own risk.")
return cmd
}
// Gas flag parsing functions
// GasSetting encapsulates the possible values passed through the --gas flag.

View File

@ -1,128 +0,0 @@
package lcd
import (
"fmt"
"net"
"net/http"
"os"
"time"
"github.com/gorilla/handlers"
"github.com/gorilla/mux"
"github.com/rakyll/statik/fs"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/tendermint/tendermint/libs/log"
tmrpcserver "github.com/tendermint/tendermint/rpc/jsonrpc/server"
"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"
// unnamed import of statik for swagger UI support
_ "github.com/cosmos/cosmos-sdk/client/lcd/statik"
)
// RestServer represents the Light Client Rest server
type RestServer struct {
Mux *mux.Router
ClientCtx client.Context
log log.Logger
listener net.Listener
}
// NewRestServer creates a new rest server instance
func NewRestServer(cdc *codec.Codec) *RestServer {
r := mux.NewRouter()
clientCtx := client.NewContext().WithCodec(cdc)
logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)).With("module", "rest-server")
return &RestServer{
Mux: r,
ClientCtx: clientCtx,
log: logger,
}
}
// StartWithConfig starts the REST server that listens on the provided listenAddr.
// It will use the provided RPC configuration.
func (rs *RestServer) StartWithConfig(listenAddr string, cors bool, cfg *tmrpcserver.Config) error {
server.TrapSignal(func() {
err := rs.listener.Close()
rs.log.Error("error closing listener", "err", err)
})
listener, err := tmrpcserver.Listen(listenAddr, cfg)
if err != nil {
return err
}
rs.listener = listener
rs.log.Info(
fmt.Sprintf("Starting application REST service (chain-id: %q)...", viper.GetString(flags.FlagChainID)),
)
var h http.Handler = rs.Mux
if cors {
return tmrpcserver.Serve(rs.listener, handlers.CORS()(h), rs.log, cfg)
}
return tmrpcserver.Serve(rs.listener, rs.Mux, rs.log, cfg)
}
// Start starts the REST server that listens on the provided listenAddr. The REST
// service will use Tendermint's default RPC configuration, where the R/W timeout
// and max open connections are overridden.
func (rs *RestServer) Start(listenAddr string, maxOpen int, readTimeout, writeTimeout uint, cors bool) error {
cfg := tmrpcserver.DefaultConfig()
cfg.MaxOpenConnections = maxOpen
cfg.ReadTimeout = time.Duration(readTimeout) * time.Second
cfg.WriteTimeout = time.Duration(writeTimeout) * time.Second
return rs.StartWithConfig(listenAddr, cors, cfg)
}
// ServeCommand will start the application REST service as a blocking process. It
// takes a codec to create a RestServer object and a function to register all
// necessary routes.
func ServeCommand(cdc *codec.Codec, registerRoutesFn func(*RestServer)) *cobra.Command {
cmd := &cobra.Command{
Use: "rest-server",
Short: "Start LCD (light-client daemon), a local REST server",
RunE: func(cmd *cobra.Command, args []string) (err error) {
rs := NewRestServer(cdc)
registerRoutesFn(rs)
rs.registerSwaggerUI()
cfg := tmrpcserver.DefaultConfig()
cfg.MaxOpenConnections = viper.GetInt(flags.FlagMaxOpenConnections)
cfg.ReadTimeout = time.Duration(viper.GetInt64(flags.FlagRPCReadTimeout)) * time.Second
cfg.WriteTimeout = time.Duration(viper.GetInt64(flags.FlagRPCWriteTimeout)) * time.Second
cfg.MaxBodyBytes = viper.GetInt64(flags.FlagRPCMaxBodyBytes)
// start the rest server and return error if one exists
return rs.StartWithConfig(
viper.GetString(flags.FlagListenAddr),
viper.GetBool(flags.FlagUnsafeCORS),
cfg,
)
},
}
return flags.RegisterRestServerFlags(cmd)
}
func (rs *RestServer) registerSwaggerUI() {
statikFS, err := fs.New()
if err != nil {
panic(err)
}
staticServer := http.FileServer(statikFS)
rs.Mux.PathPrefix("/").Handler(staticServer)
}

View File

@ -6,6 +6,7 @@ services:
image: "cosmos-sdk/simappnode"
ports:
- "26656-26657:26656-26657"
- "1317:1317"
environment:
- ID=0
- LOG=${LOG:-simd.log}
@ -20,6 +21,7 @@ services:
image: "cosmos-sdk/simappnode"
ports:
- "26659-26660:26656-26657"
- "1318:1317"
environment:
- ID=1
- LOG=${LOG:-simd.log}
@ -37,6 +39,7 @@ services:
- LOG=${LOG:-simd.log}
ports:
- "26661-26662:26656-26657"
- "1319:1317"
volumes:
- ./build:/simd:Z
networks:
@ -51,6 +54,7 @@ services:
- LOG=${LOG:-simd.log}
ports:
- "26663-26664:26656-26657"
- "1320:1317"
volumes:
- ./build:/simd:Z
networks:

View File

@ -15,7 +15,7 @@ RUN apt-get update && \
VOLUME [ /simd ]
WORKDIR /simd
EXPOSE 26656 26657
EXPOSE 26656 26657 1317
ENTRYPOINT ["/usr/bin/wrapper.sh"]
CMD ["start"]
STOPSIGNAL SIGTERM

77
server/api/server.go Normal file
View File

@ -0,0 +1,77 @@
package api
import (
"net"
"net/http"
"os"
"time"
"github.com/gorilla/handlers"
"github.com/gorilla/mux"
"github.com/rakyll/statik/fs"
"github.com/tendermint/tendermint/libs/log"
tmrpcserver "github.com/tendermint/tendermint/rpc/jsonrpc/server"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/server/config"
// unnamed import of statik for swagger UI support
_ "github.com/cosmos/cosmos-sdk/client/docs/statik"
)
// Server defines the server's API interface.
type Server struct {
Router *mux.Router
ClientCtx client.Context
logger log.Logger
listener net.Listener
}
func New(clientCtx client.Context) *Server {
return &Server{
Router: mux.NewRouter(),
ClientCtx: clientCtx,
logger: log.NewTMLogger(log.NewSyncWriter(os.Stdout)).With("module", "api-server"),
}
}
// Start starts the API server. Internally, the API server leverages Tendermint's
// JSON RPC server. Configuration options are provided via config.APIConfig
// and are delegated to the Tendermint JSON RPC server. The process is
// non-blocking, so an external signal handler must be used.
func (s *Server) Start(cfg config.APIConfig) error {
if cfg.Swagger {
s.registerSwaggerUI()
}
tmCfg := tmrpcserver.DefaultConfig()
tmCfg.MaxOpenConnections = int(cfg.MaxOpenConnections)
tmCfg.ReadTimeout = time.Duration(cfg.RPCReadTimeout) * time.Second
tmCfg.WriteTimeout = time.Duration(cfg.RPCWriteTimeout) * time.Second
tmCfg.MaxBodyBytes = int64(cfg.RPCMaxBodyBytes)
listener, err := tmrpcserver.Listen(cfg.Address, tmCfg)
if err != nil {
return err
}
s.listener = listener
var h http.Handler = s.Router
if cfg.EnableUnsafeCORS {
return tmrpcserver.Serve(s.listener, handlers.CORS()(h), s.logger, tmCfg)
}
return tmrpcserver.Serve(s.listener, s.Router, s.logger, tmCfg)
}
func (s *Server) registerSwaggerUI() {
statikFS, err := fs.New()
if err != nil {
panic(err)
}
staticServer := http.FileServer(statikFS)
s.Router.PathPrefix("/").Handler(staticServer)
}

View File

@ -19,6 +19,10 @@ type BaseConfig struct {
// specified in this config (e.g. 0.25token1;0.0001token2).
MinGasPrices string `mapstructure:"minimum-gas-prices"`
Pruning string `mapstructure:"pruning"`
PruningKeepEvery string `mapstructure:"pruning-keep-every"`
PruningSnapshotEvery string `mapstructure:"pruning-snapshot-every"`
// HaltHeight contains a non-zero block height at which a node will gracefully
// halt and shutdown that can be used to assist upgrades and testing.
//
@ -34,15 +38,44 @@ type BaseConfig struct {
// InterBlockCache enables inter-block caching.
InterBlockCache bool `mapstructure:"inter-block-cache"`
}
Pruning string `mapstructure:"pruning"`
PruningKeepEvery string `mapstructure:"pruning-keep-every"`
PruningSnapshotEvery string `mapstructure:"pruning-snapshot-every"`
// APIConfig defines the API listener configuration.
type APIConfig struct {
// Enable defines if the API server should be enabled.
Enable bool `mapstructure:"enable"`
// Swagger defines if swagger documentation should automatically be registered.
Swagger bool `mapstructure:"swagger"`
// EnableUnsafeCORS defines if CORS should be enabled (unsafe - use it at your own risk)
EnableUnsafeCORS bool `mapstructure:"enabled-unsafe-cors"`
// Address defines the API server to listen on
Address string `mapstructure:"address"`
// MaxOpenConnections defines the number of maximum open connections
MaxOpenConnections uint `mapstructure:"max-open-connections"`
// RPCReadTimeout defines the Tendermint RPC read timeout (in seconds)
RPCReadTimeout uint `mapstructure:"rpc-read-timeout"`
// RPCWriteTimeout defines the Tendermint RPC write timeout (in seconds)
RPCWriteTimeout uint `mapstructure:"rpc-write-timeout"`
// RPCMaxBodyBytes defines the Tendermint maximum response body (in bytes)
RPCMaxBodyBytes uint `mapstructure:"rpc-max-body-bytes"`
// TODO: TLS/Proxy configuration.
//
// Ref: https://github.com/cosmos/cosmos-sdk/issues/6420
}
// Config defines the server's top level configuration
type Config struct {
BaseConfig `mapstructure:",squash"`
API APIConfig `mapstructure:"api"`
}
// SetMinGasPrices sets the validator's minimum gas prices.
@ -75,12 +108,20 @@ func (c *Config) GetMinGasPrices() sdk.DecCoins {
// DefaultConfig returns server's default configuration.
func DefaultConfig() *Config {
return &Config{
BaseConfig{
BaseConfig: BaseConfig{
MinGasPrices: defaultMinGasPrices,
InterBlockCache: true,
Pruning: store.PruningStrategySyncable,
PruningKeepEvery: "0",
PruningSnapshotEvery: "0",
},
API: APIConfig{
Enable: false,
Swagger: false,
Address: "tcp://0.0.0.0:1317",
MaxOpenConnections: 1000,
RPCReadTimeout: 10,
RPCMaxBodyBytes: 1000000,
},
}
}

View File

@ -11,13 +11,26 @@ import (
const defaultConfigTemplate = `# This is a TOML config file.
# For more information, see https://github.com/toml-lang/toml
##### main base config options #####
###############################################################################
### Base Configuration ###
###############################################################################
# The minimum gas prices a validator is willing to accept for processing a
# transaction. A transaction's fees must meet the minimum of any denomination
# specified in this config (e.g. 0.25token1;0.0001token2).
minimum-gas-prices = "{{ .BaseConfig.MinGasPrices }}"
# Pruning sets the pruning strategy: syncable, nothing, everything, custom
# syncable: only those states not needed for state syncing will be deleted (keeps last 100 + every 10000th)
# nothing: all historic states will be saved, nothing will be deleted (i.e. archiving node)
# everything: all saved states will be deleted, storing only the current state
# custom: allows fine-grained control through the pruning-keep-every and pruning-snapshot-every options.
pruning = "{{ .BaseConfig.Pruning }}"
# These are applied if and only if the pruning strategy is custom.
pruning-keep-every = "{{ .BaseConfig.PruningKeepEvery }}"
pruning-snapshot-every = "{{ .BaseConfig.PruningSnapshotEvery }}"
# HaltHeight contains a non-zero block height at which a node will gracefully
# halt and shutdown that can be used to assist upgrades and testing.
#
@ -34,16 +47,35 @@ halt-time = {{ .BaseConfig.HaltTime }}
# InterBlockCache enables inter-block caching.
inter-block-cache = {{ .BaseConfig.InterBlockCache }}
# Pruning sets the pruning strategy: syncable, nothing, everything, custom
# syncable: only those states not needed for state syncing will be deleted (keeps last 100 + every 10000th)
# nothing: all historic states will be saved, nothing will be deleted (i.e. archiving node)
# everything: all saved states will be deleted, storing only the current state
# custom: allows fine-grained control through the pruning-keep-every and pruning-snapshot-every options.
pruning = "{{ .BaseConfig.Pruning }}"
###############################################################################
### API Configuration ###
###############################################################################
# These are applied if and only if the pruning strategy is custom.
pruning-keep-every = "{{ .BaseConfig.PruningKeepEvery }}"
pruning-snapshot-every = "{{ .BaseConfig.PruningSnapshotEvery }}"
[api]
# Enable defines if the API server should be enabled.
enable = {{ .API.Enable }}
# Swagger defines if swagger documentation should automatically be registered.
swagger = {{ .API.Swagger }}
# Address defines the API server to listen on
address = "{{ .API.Address }}"
# MaxOpenConnections defines the number of maximum open connections
max-open-connections = {{ .API.MaxOpenConnections }}
# RPCReadTimeout defines the Tendermint RPC read timeout (in seconds)
rpc-read-timeout = {{ .API.RPCReadTimeout }}
# RPCWriteTimeout defines the Tendermint RPC write timeout (in seconds)
rpc-write-timeout = {{ .API.RPCWriteTimeout }}
# RPCMaxBodyBytes defines the Tendermint maximum response body (in bytes)
rpc-max-body-bytes = {{ .API.RPCMaxBodyBytes }}
# EnableUnsafeCORS defines if CORS should be enabled (unsafe - use it at your own risk)
enabled-unsafe-cors = {{ .API.EnableUnsafeCORS }}
`
var configTemplate *template.Template

View File

@ -11,13 +11,23 @@ import (
tmtypes "github.com/tendermint/tendermint/types"
dbm "github.com/tendermint/tm-db"
"github.com/cosmos/cosmos-sdk/server/api"
sdk "github.com/cosmos/cosmos-sdk/types"
)
type (
// 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.
Application interface {
abci.Application
RegisterAPIRoutes(*api.Server)
}
// AppCreator is a function that allows us to lazily initialize an
// application using various configurations.
AppCreator func(log.Logger, dbm.DB, io.Writer) abci.Application
AppCreator func(log.Logger, dbm.DB, io.Writer) Application
// AppExporter is a function that dumps all app state to
// JSON-serializable structure and returns the current validator set.

View File

@ -16,6 +16,12 @@ import (
"github.com/tendermint/tendermint/p2p"
pvm "github.com/tendermint/tendermint/privval"
"github.com/tendermint/tendermint/proxy"
"github.com/tendermint/tendermint/rpc/client/local"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/server/api"
"github.com/cosmos/cosmos-sdk/server/config"
)
// Tendermint full-node start flags
@ -36,7 +42,7 @@ const (
// StartCmd runs the service passed in, either stand-alone or in-process with
// Tendermint.
func StartCmd(ctx *Context, appCreator AppCreator) *cobra.Command {
func StartCmd(ctx *Context, cdc codec.JSONMarshaler, appCreator AppCreator) *cobra.Command {
cmd := &cobra.Command{
Use: "start",
Short: "Run the full node",
@ -72,7 +78,7 @@ which accepts a path for the resulting pprof file.
ctx.Logger.Info("starting ABCI with Tendermint")
err := startInProcess(ctx, appCreator)
err := startInProcess(ctx, cdc, appCreator)
return err
},
}
@ -143,7 +149,7 @@ func startStandAlone(ctx *Context, appCreator AppCreator) error {
select {}
}
func startInProcess(ctx *Context, appCreator AppCreator) error {
func startInProcess(ctx *Context, cdc codec.JSONMarshaler, appCreator AppCreator) error {
cfg := ctx.Config
home := cfg.RootDir
@ -165,13 +171,15 @@ func startInProcess(ctx *Context, appCreator AppCreator) error {
return err
}
genDocProvider := node.DefaultGenesisDocProviderFunc(cfg)
// create & start tendermint node
tmNode, err := node.NewNode(
cfg,
pvm.LoadOrGenFilePV(cfg.PrivValidatorKeyFile(), cfg.PrivValidatorStateFile()),
nodeKey,
proxy.NewLocalClientCreator(app),
node.DefaultGenesisDocProviderFunc(cfg),
genDocProvider,
node.DefaultDBProvider,
node.DefaultMetricsProvider(cfg.Instrumentation),
ctx.Logger.With("module", "node"),
@ -184,6 +192,39 @@ func startInProcess(ctx *Context, appCreator AppCreator) error {
return err
}
if viper.GetBool("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.
ctx := client.Context{}.
WithHomeDir(home).
WithChainID(genDoc.ChainID).
WithJSONMarshaler(cdc).
WithClient(local.New(tmNode)).
WithTrustNode(true)
apiSrv := api.New(ctx)
apiCfg := config.APIConfig{
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"),
}
app.RegisterAPIRoutes(apiSrv)
if err := apiSrv.Start(apiCfg); err != nil {
return err
}
}
var cpuProfileCleanup func()
if cpuProfile := viper.GetString(flagCPUProfile); cpuProfile != "" {

View File

@ -71,7 +71,7 @@ func TestPruningOptions(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
viper.Reset()
viper.SetDefault(flagPruning, "syncable")
startCommand := StartCmd(nil, nil)
startCommand := StartCmd(nil, nil, nil)
tt.paramInit()
err := startCommand.PreRunE(startCommand, nil)

View File

@ -122,9 +122,8 @@ func interceptLoadConfig() (conf *cfg.Config, err error) {
// add server commands
func AddCommands(
ctx *Context, cdc codec.JSONMarshaler,
rootCmd *cobra.Command,
appCreator AppCreator, appExport AppExporter) {
ctx *Context, cdc codec.JSONMarshaler, rootCmd *cobra.Command, appCreator AppCreator, appExport AppExporter,
) {
rootCmd.PersistentFlags().String("log_level", ctx.Config.LogLevel, "Log level")
@ -141,7 +140,7 @@ func AddCommands(
)
rootCmd.AddCommand(
StartCmd(ctx, appCreator),
StartCmd(ctx, cdc, appCreator),
UnsafeResetAllCmd(ctx),
flags.LineBreak,
tendermintCmd,

View File

@ -10,15 +10,18 @@ import (
dbm "github.com/tendermint/tm-db"
"github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/client/rpc"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/codec/testdata"
"github.com/cosmos/cosmos-sdk/codec/types"
"github.com/cosmos/cosmos-sdk/server/api"
"github.com/cosmos/cosmos-sdk/std"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/module"
"github.com/cosmos/cosmos-sdk/version"
"github.com/cosmos/cosmos-sdk/x/auth"
"github.com/cosmos/cosmos-sdk/x/auth/ante"
authrest "github.com/cosmos/cosmos-sdk/x/auth/client/rest"
"github.com/cosmos/cosmos-sdk/x/bank"
bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
@ -499,6 +502,14 @@ func (app *SimApp) SimulationManager() *module.SimulationManager {
return app.sm
}
// RegisterAPIRoutes registers all application module routes with the provided
// API server.
func (app *SimApp) RegisterAPIRoutes(apiSvr *api.Server) {
rpc.RegisterRoutes(apiSvr.ClientCtx, apiSvr.Router)
authrest.RegisterTxRoutes(apiSvr.ClientCtx, apiSvr.Router)
ModuleBasics.RegisterRESTRoutes(apiSvr.ClientCtx, apiSvr.Router)
}
// GetMaccPerms returns a copy of the module account permissions
func GetMaccPerms() map[string][]string {
dupMaccPerms := make(map[string][]string)

View File

@ -12,14 +12,12 @@ import (
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/client/keys"
"github.com/cosmos/cosmos-sdk/client/lcd"
"github.com/cosmos/cosmos-sdk/client/rpc"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/simapp"
sdk "github.com/cosmos/cosmos-sdk/types"
authclient "github.com/cosmos/cosmos-sdk/x/auth/client"
authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli"
authrest "github.com/cosmos/cosmos-sdk/x/auth/client/rest"
"github.com/cosmos/cosmos-sdk/x/auth/types"
bankcmd "github.com/cosmos/cosmos-sdk/x/bank/client/cli"
)
@ -65,7 +63,6 @@ func main() {
queryCmd(cdc),
txCmd(cdc),
flags.LineBreak,
lcd.ServeCommand(cdc, registerRoutes),
flags.LineBreak,
keys.Commands(),
flags.LineBreak,
@ -148,14 +145,6 @@ func txCmd(cdc *codec.Codec) *cobra.Command {
return txCmd
}
// registerRoutes registers the routes from the different modules for the REST client.
// NOTE: details on the routes added for each module are in the module documentation
func registerRoutes(rs *lcd.RestServer) {
rpc.RegisterRoutes(rs.ClientCtx, rs.Mux)
authrest.RegisterTxRoutes(rs.ClientCtx, rs.Mux)
simapp.ModuleBasics.RegisterRESTRoutes(rs.ClientCtx, rs.Mux)
}
func initConfig(cmd *cobra.Command) error {
home, err := cmd.PersistentFlags().GetString(cli.HomeFlag)
if err != nil {

View File

@ -71,7 +71,7 @@ func main() {
}
}
func newApp(logger log.Logger, db dbm.DB, traceStore io.Writer) abci.Application {
func newApp(logger log.Logger, db dbm.DB, traceStore io.Writer) server.Application {
var cache sdk.MultiStorePersistentCache
if viper.GetBool(server.FlagInterBlockCache) {

View File

@ -121,6 +121,7 @@ func InitTestnet(
simappConfig := srvconfig.DefaultConfig()
simappConfig.MinGasPrices = minGasPrices
simappConfig.API.Enable = true
var (
genAccounts []authtypes.GenesisAccount