cosmos-sdk/server/start.go

187 lines
4.7 KiB
Go
Raw Normal View History

package server
// DONTCOVER
import (
"fmt"
"os"
"runtime/pprof"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/tendermint/tendermint/abci/server"
tcmd "github.com/tendermint/tendermint/cmd/tendermint/commands"
cmn "github.com/tendermint/tendermint/libs/common"
"github.com/tendermint/tendermint/node"
"github.com/tendermint/tendermint/p2p"
2018-06-05 18:04:16 -07:00
pvm "github.com/tendermint/tendermint/privval"
"github.com/tendermint/tendermint/proxy"
)
2019-01-18 08:45:20 -08:00
// Tendermint full-node start flags
const (
flagWithTendermint = "with-tendermint"
flagAddress = "address"
flagTraceStore = "trace-store"
flagPruning = "pruning"
flagCPUProfile = "cpu-profile"
FlagMinGasPrices = "minimum-gas-prices"
FlagHaltHeight = "halt-height"
FlagInterBlockCache = "inter-block-cache"
)
// StartCmd runs the service passed in, either stand-alone or in-process with
// Tendermint.
2018-04-27 17:36:11 -07:00
func StartCmd(ctx *Context, appCreator AppCreator) *cobra.Command {
cmd := &cobra.Command{
Use: "start",
Short: "Run the full node",
2018-04-21 19:26:46 -07:00
RunE: func(cmd *cobra.Command, args []string) error {
if !viper.GetBool(flagWithTendermint) {
ctx.Logger.Info("starting ABCI without Tendermint")
2018-04-21 19:26:46 -07:00
return startStandAlone(ctx, appCreator)
}
ctx.Logger.Info("starting ABCI with Tendermint")
2018-07-01 12:10:45 -07:00
_, err := startInProcess(ctx, appCreator)
return err
2018-04-21 19:26:46 -07:00
},
}
2018-04-21 19:26:46 -07:00
// core flags for the ABCI application
cmd.Flags().Bool(flagWithTendermint, true, "Run abci app embedded in-process with tendermint")
cmd.Flags().String(flagAddress, "tcp://0.0.0.0:26658", "Listen address")
cmd.Flags().String(flagTraceStore, "", "Enable KVStore tracing to an output file")
2018-07-12 18:20:26 -07:00
cmd.Flags().String(flagPruning, "syncable", "Pruning strategy: syncable, nothing, everything")
2019-01-18 08:45:20 -08:00
cmd.Flags().String(
FlagMinGasPrices, "",
"Minimum gas prices to accept for transactions; Any fee in a tx must meet this minimum (e.g. 0.01photino;0.0001stake)",
2019-01-18 08:45:20 -08:00
)
cmd.Flags().Uint64(FlagHaltHeight, 0, "Height at which to gracefully halt the chain and shutdown the node")
cmd.Flags().Bool(FlagInterBlockCache, true, "Enable inter-block caching")
cmd.Flags().String(flagCPUProfile, "", "Enable CPU profiling and write to the provided file")
// add support for all Tendermint-specific command line options
tcmd.AddNodeFlags(cmd)
return cmd
}
2018-04-27 17:36:11 -07:00
func startStandAlone(ctx *Context, appCreator AppCreator) error {
addr := viper.GetString(flagAddress)
2018-02-21 09:56:04 -08:00
home := viper.GetString("home")
traceWriterFile := viper.GetString(flagTraceStore)
db, err := openDB(home)
2018-02-21 09:56:04 -08:00
if err != nil {
return err
}
traceWriter, err := openTraceWriter(traceWriterFile)
if err != nil {
return err
}
app := appCreator(ctx.Logger, db, traceWriter)
2018-02-21 09:56:04 -08:00
svr, err := server.NewServer(addr, "socket", app)
if err != nil {
return fmt.Errorf("error creating listener: %v", err)
}
2018-04-21 19:26:46 -07:00
svr.SetLogger(ctx.Logger.With("module", "abci-server"))
err = svr.Start()
if err != nil {
cmn.Exit(err.Error())
}
cmn.TrapSignal(ctx.Logger, func() {
// cleanup
err = svr.Stop()
if err != nil {
cmn.Exit(err.Error())
}
})
// run forever (the node will not be returned)
select {}
}
2018-07-01 12:10:45 -07:00
func startInProcess(ctx *Context, appCreator AppCreator) (*node.Node, error) {
2018-04-21 19:26:46 -07:00
cfg := ctx.Config
2018-02-21 09:56:04 -08:00
home := cfg.RootDir
traceWriterFile := viper.GetString(flagTraceStore)
db, err := openDB(home)
2018-02-21 09:56:04 -08:00
if err != nil {
2018-07-01 12:10:45 -07:00
return nil, err
2018-02-21 09:56:04 -08:00
}
traceWriter, err := openTraceWriter(traceWriterFile)
if err != nil {
return nil, err
}
app := appCreator(ctx.Logger, db, traceWriter)
2018-02-21 09:56:04 -08:00
nodeKey, err := p2p.LoadOrGenNodeKey(cfg.NodeKeyFile())
if err != nil {
return nil, err
}
UpgradeOldPrivValFile(cfg)
// create & start tendermint node
tmNode, err := node.NewNode(
cfg,
pvm.LoadOrGenFilePV(cfg.PrivValidatorKeyFile(), cfg.PrivValidatorStateFile()),
nodeKey,
2018-02-21 09:56:04 -08:00
proxy.NewLocalClientCreator(app),
node.DefaultGenesisDocProviderFunc(cfg),
node.DefaultDBProvider,
node.DefaultMetricsProvider(cfg.Instrumentation),
ctx.Logger.With("module", "node"),
)
if err != nil {
2018-07-01 12:10:45 -07:00
return nil, err
}
if err := tmNode.Start(); err != nil {
2018-07-01 12:10:45 -07:00
return nil, err
}
var cpuProfileCleanup func()
if cpuProfile := viper.GetString(flagCPUProfile); cpuProfile != "" {
f, err := os.Create(cpuProfile)
if err != nil {
return nil, err
}
ctx.Logger.Info("starting CPU profiler", "profile", cpuProfile)
if err := pprof.StartCPUProfile(f); err != nil {
return nil, err
}
cpuProfileCleanup = func() {
ctx.Logger.Info("stopping CPU profiler", "profile", cpuProfile)
pprof.StopCPUProfile()
f.Close()
}
}
TrapSignal(func() {
if tmNode.IsRunning() {
_ = tmNode.Stop()
}
if cpuProfileCleanup != nil {
cpuProfileCleanup()
}
ctx.Logger.Info("exiting...")
})
// run forever (the node will not be returned)
select {}
}