Documentation
¶
Index ¶
Constants ¶
This section is empty.
Variables ¶
View Source
var AdvanceBlockCmd *cli.Command
View Source
var DaemonCmd = &cli.Command{ Name: "daemon", Usage: "Start a lotus daemon process", Flags: []cli.Flag{ &cli.StringFlag{ Name: "api", Value: "1234", }, &cli.StringFlag{ Name: makeGenFlag, Value: "", Hidden: true, }, &cli.StringFlag{ Name: preTemplateFlag, Hidden: true, }, &cli.StringFlag{ Name: "import-key", Usage: "on first run, import a default key from a given file", Hidden: true, }, &cli.StringFlag{ Name: "genesis", Usage: "genesis file to use for first node run", }, &cli.BoolFlag{ Name: "bootstrap", Value: true, }, &cli.StringFlag{ Name: "import-chain", Usage: "on first run, load chain from given file or url and validate", }, &cli.StringFlag{ Name: "import-snapshot", Usage: "import chain state from a given chain export file or url", }, &cli.BoolFlag{ Name: "remove-existing-chain", Usage: "remove existing chain and splitstore data on a snapshot-import", }, &cli.BoolFlag{ Name: "halt-after-import", Usage: "halt the process after importing chain from file", }, &cli.BoolFlag{ Name: "lite", Usage: "start lotus in lite mode", }, &cli.StringFlag{ Name: "pprof", Usage: "specify name of file for writing cpu profile to", }, &cli.StringFlag{ Name: "profile", Usage: "specify type of node", }, &cli.BoolFlag{ Name: "manage-fdlimit", Usage: "manage open file limit", Value: true, }, &cli.StringFlag{ Name: "config", Usage: "specify path of config file to use", }, &cli.IntFlag{ Name: "api-max-req-size", Usage: "maximum API request size accepted by the JSON RPC server", }, &cli.PathFlag{ Name: "restore", Usage: "restore from backup file", }, &cli.PathFlag{ Name: "restore-config", Usage: "config file to use when restoring from backup", }, }, Action: func(cctx *cli.Context) error { isLite := cctx.Bool("lite") err := runmetrics.Enable(runmetrics.RunMetricOptions{ EnableCPU: true, EnableMemory: true, }) if err != nil { return xerrors.Errorf("enabling runtime metrics: %w", err) } interactive := cctx.Bool("interactive") if cctx.Bool("manage-fdlimit") { if _, _, err := ulimit.ManageFdLimit(); err != nil { log.Errorf("setting file descriptor limit: %s", err) } } if prof := cctx.String("pprof"); prof != "" { profile, err := os.Create(prof) if err != nil { return err } if err := pprof.StartCPUProfile(profile); err != nil { return err } defer pprof.StopCPUProfile() } var isBootstrapper dtypes.Bootstrapper switch profile := cctx.String("profile"); profile { case "bootstrapper": isBootstrapper = true case "": default: return fmt.Errorf("unrecognized profile type: %q", profile) } ctx, _ := tag.New(context.Background(), tag.Insert(metrics.Version, build.NodeBuildVersion), tag.Insert(metrics.Commit, build.CurrentCommit), tag.Insert(metrics.NodeType, "chain"), ) ctx = metrics.AddNetworkTag(ctx) if err = view.Register( metrics.ChainNodeViews..., ); err != nil { log.Fatalf("Cannot register the view: %v", err) } stats.Record(ctx, metrics.LotusInfo.M(1)) { dir, err := homedir.Expand(cctx.String("repo")) if err != nil { log.Warnw("could not expand repo location", "error", err) } else { log.Infof("lotus repo: %s", dir) } } r, err := repo.NewFS(cctx.String("repo")) if err != nil { return xerrors.Errorf("opening fs repo: %w", err) } if cctx.String("config") != "" { r.SetConfigPath(cctx.String("config")) } err = r.Init(repo.FullNode) if err != nil && err != repo.ErrRepoExists { return xerrors.Errorf("repo init error: %w", err) } freshRepo := err != repo.ErrRepoExists if !isLite { if err := paramfetch.GetParams(lcli.ReqContext(cctx), build.ParametersJSON(), build.SrsJSON(), 0); err != nil { return xerrors.Errorf("fetching proof parameters: %w", err) } } var genBytes []byte if cctx.String("genesis") != "" { genBytes, err = os.ReadFile(cctx.String("genesis")) if err != nil { return xerrors.Errorf("reading genesis: %w", err) } } else { genBytes = build.MaybeGenesis() } if cctx.IsSet("restore") { if !freshRepo { return xerrors.Errorf("restoring from backup is only possible with a fresh repo!") } if err := restore(cctx, r); err != nil { return xerrors.Errorf("restoring from backup: %w", err) } } if cctx.Bool("remove-existing-chain") { lr, err := repo.NewFS(cctx.String("repo")) if err != nil { return xerrors.Errorf("error opening fs repo: %w", err) } exists, err := lr.Exists() if err != nil { return err } if !exists { return xerrors.Errorf("lotus repo doesn't exist") } err = removeExistingChain(cctx, lr) if err != nil { return err } } chainfile := cctx.String("import-chain") snapshot := cctx.String("import-snapshot") willImportChain := false if chainfile != "" || snapshot != "" { if chainfile != "" && snapshot != "" { return fmt.Errorf("cannot specify both 'import-snapshot' and 'import-chain'") } willImportChain = true } var willRemoveChain bool if interactive && willImportChain && !cctx.IsSet("remove-existing-chain") { reader := bufio.NewReader(os.Stdin) fmt.Print("Importing chain or snapshot will by default delete existing local chain data. Do you want to proceed and delete? (yes/no): ") userInput, err := reader.ReadString('\n') if err != nil { return xerrors.Errorf("reading user input: %w", err) } userInput = strings.ToLower(strings.TrimSpace(userInput)) switch userInput { case "yes": willRemoveChain = true case "no": willRemoveChain = false default: return fmt.Errorf("invalid input. please answer with 'yes' or 'no'") } } else { willRemoveChain = cctx.Bool("remove-existing-chain") } if willRemoveChain { lr, err := repo.NewFS(cctx.String("repo")) if err != nil { return xerrors.Errorf("error opening fs repo: %w", err) } exists, err := lr.Exists() if err != nil { return err } if !exists { return xerrors.Errorf("lotus repo doesn't exist") } err = removeExistingChain(cctx, lr) if err != nil { return err } } if willImportChain { var issnapshot bool if chainfile == "" { chainfile = snapshot issnapshot = true } if err := ImportChain(ctx, r, chainfile, issnapshot); err != nil { return err } if cctx.Bool("halt-after-import") { fmt.Println("Chain import complete, halting as requested...") return nil } } genesis := node.Options() if len(genBytes) > 0 { genesis = node.Override(new(modules.Genesis), modules.LoadGenesis(genBytes)) } if cctx.String(makeGenFlag) != "" { if cctx.String(preTemplateFlag) == "" { return xerrors.Errorf("must also pass file with genesis template to `--%s`", preTemplateFlag) } genesis = node.Override(new(modules.Genesis), testing.MakeGenesis(cctx.String(makeGenFlag), cctx.String(preTemplateFlag))) } shutdownChan := make(chan struct{}) liteModeDeps := node.Options() if isLite { gapi, closer, err := lcli.GetGatewayAPI(cctx) if err != nil { return err } defer closer() liteModeDeps = node.Override(new(lapi.Gateway), gapi) } if err := metricsprom.Inject(); err != nil { log.Warnf("unable to inject prometheus ipfs/go-metrics exporter; some metrics will be unavailable; err: %s", err) } var api lapi.FullNode stop, err := node.New(ctx, node.FullAPI(&api, node.Lite(isLite)), node.Base(), node.Repo(r), node.Override(new(dtypes.Bootstrapper), isBootstrapper), node.Override(new(dtypes.ShutdownChan), shutdownChan), genesis, liteModeDeps, node.ApplyIf(func(s *node.Settings) bool { return cctx.IsSet("api") }, node.Override(node.SetApiEndpointKey, func(lr repo.LockedRepo) error { apima, err := multiaddr.NewMultiaddr("/ip4/127.0.0.1/tcp/" + cctx.String("api")) if err != nil { return err } return lr.SetAPIEndpoint(apima) })), node.ApplyIf(func(s *node.Settings) bool { return !cctx.Bool("bootstrap") }, node.Unset(node.RunPeerMgrKey), node.Unset(new(*peermgr.PeerMgr)), ), ) if err != nil { return xerrors.Errorf("initializing node: %w", err) } if cctx.String("import-key") != "" { if err := importKey(ctx, api, cctx.String("import-key")); err != nil { log.Errorf("importing key failed: %+v", err) } } endpoint, err := r.APIEndpoint() if err != nil { return xerrors.Errorf("getting api endpoint: %w", err) } serverOptions := []jsonrpc.ServerOption{jsonrpc.WithServerErrors(lapi.RPCErrors)} if maxRequestSize := cctx.Int("api-max-req-size"); maxRequestSize != 0 { serverOptions = append(serverOptions, jsonrpc.WithMaxRequestSize(int64(maxRequestSize))) } h, err := node.FullNodeHandler(api, true, serverOptions...) if err != nil { return fmt.Errorf("failed to instantiate rpc handler: %s", err) } rpcStopper, err := node.ServeRPC(h, "lotus-daemon", endpoint) if err != nil { return fmt.Errorf("failed to start json-rpc endpoint: %s", err) } finishCh := node.MonitorShutdown(shutdownChan, node.ShutdownHandler{Component: "rpc server", StopFunc: rpcStopper}, node.ShutdownHandler{Component: "node", StopFunc: stop}, ) <-finishCh return nil }, Subcommands: []*cli.Command{ daemonStopCmd, }, }
DaemonCmd is the `go-lotus daemon` command
Functions ¶
Types ¶
This section is empty.
Click to show internal directories.
Click to hide internal directories.