Merge PR #6426: Migrate API Server
This commit is contained in:
parent
6336f95802
commit
6a05b83069
|
@ -1 +1 @@
|
|||
client/lcd/swagger-ui/* linguist-vendored
|
||||
client/docs/swagger-ui/* linguist-vendored
|
||||
|
|
|
@ -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.
|
||||
|
|
6
Makefile
6
Makefile
|
@ -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
|
||||
|
||||
###############################################################################
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
Before Width: | Height: | Size: 445 B After Width: | Height: | Size: 445 B |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
}
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
}
|
|
@ -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,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 != "" {
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -121,6 +121,7 @@ func InitTestnet(
|
|||
|
||||
simappConfig := srvconfig.DefaultConfig()
|
||||
simappConfig.MinGasPrices = minGasPrices
|
||||
simappConfig.API.Enable = true
|
||||
|
||||
var (
|
||||
genAccounts []authtypes.GenesisAccount
|
||||
|
|
Loading…
Reference in New Issue