lotus/cmd/lotus-storage-miner/run.go
Steven Allen 5733c71c50 Lint everything
We were ignoring quite a few error cases, and had one case where we weren't
actually updating state where we wanted to. Unfortunately, if the linter doesn't
pass, nobody has any reason to actually check lint failures in CI.

There are three remaining XXXs marked in the code for lint.
2020-08-20 20:46:36 -07:00

184 lines
4.3 KiB
Go

package main
import (
"context"
"net/http"
_ "net/http/pprof"
"os"
"os/signal"
"syscall"
mux "github.com/gorilla/mux"
"github.com/multiformats/go-multiaddr"
manet "github.com/multiformats/go-multiaddr-net"
"github.com/urfave/cli/v2"
"golang.org/x/xerrors"
"github.com/filecoin-project/go-jsonrpc"
"github.com/filecoin-project/go-jsonrpc/auth"
"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/api/apistruct"
"github.com/filecoin-project/lotus/build"
lcli "github.com/filecoin-project/lotus/cli"
"github.com/filecoin-project/lotus/lib/ulimit"
"github.com/filecoin-project/lotus/node"
"github.com/filecoin-project/lotus/node/impl"
"github.com/filecoin-project/lotus/node/modules/dtypes"
"github.com/filecoin-project/lotus/node/repo"
)
var runCmd = &cli.Command{
Name: "run",
Usage: "Start a lotus miner process",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "api",
Usage: "2345",
},
&cli.BoolFlag{
Name: "enable-gpu-proving",
Usage: "enable use of GPU for mining operations",
Value: true,
},
&cli.BoolFlag{
Name: "nosync",
Usage: "don't check full-node sync status",
},
&cli.BoolFlag{
Name: "manage-fdlimit",
Usage: "manage open file limit",
Value: true,
},
},
Action: func(cctx *cli.Context) error {
if !cctx.Bool("enable-gpu-proving") {
err := os.Setenv("BELLMAN_NO_GPU", "true")
if err != nil {
return err
}
}
nodeApi, ncloser, err := lcli.GetFullNodeAPI(cctx)
if err != nil {
return err
}
defer ncloser()
ctx := lcli.DaemonContext(cctx)
v, err := nodeApi.Version(ctx)
if err != nil {
return err
}
if cctx.Bool("manage-fdlimit") {
if _, _, err := ulimit.ManageFdLimit(); err != nil {
log.Errorf("setting file descriptor limit: %s", err)
}
}
if v.APIVersion != build.APIVersion {
return xerrors.Errorf("lotus-daemon API version doesn't match: local: %s", api.Version{APIVersion: build.APIVersion})
}
log.Info("Checking full node sync status")
if !cctx.Bool("nosync") {
if err := lcli.SyncWait(ctx, nodeApi); err != nil {
return xerrors.Errorf("sync wait: %w", err)
}
}
minerRepoPath := cctx.String(FlagMinerRepo)
r, err := repo.NewFS(minerRepoPath)
if err != nil {
return err
}
ok, err := r.Exists()
if err != nil {
return err
}
if !ok {
return xerrors.Errorf("repo at '%s' is not initialized, run 'lotus-miner init' to set it up", minerRepoPath)
}
shutdownChan := make(chan struct{})
var minerapi api.StorageMiner
stop, err := node.New(ctx,
node.StorageMiner(&minerapi),
node.Override(new(dtypes.ShutdownChan), shutdownChan),
node.Online(),
node.Repo(r),
node.ApplyIf(func(s *node.Settings) bool { return cctx.IsSet("api") },
node.Override(new(dtypes.APIEndpoint), func() (dtypes.APIEndpoint, error) {
return multiaddr.NewMultiaddr("/ip4/127.0.0.1/tcp/" + cctx.String("api"))
})),
node.Override(new(api.FullNode), nodeApi),
)
if err != nil {
return err
}
endpoint, err := r.APIEndpoint()
if err != nil {
return err
}
// Bootstrap with full node
remoteAddrs, err := nodeApi.NetAddrsListen(ctx)
if err != nil {
return err
}
if err := minerapi.NetConnect(ctx, remoteAddrs); err != nil {
return err
}
log.Infof("Remote version %s", v)
lst, err := manet.Listen(endpoint)
if err != nil {
return xerrors.Errorf("could not listen: %w", err)
}
mux := mux.NewRouter()
rpcServer := jsonrpc.NewServer()
rpcServer.Register("Filecoin", apistruct.PermissionedStorMinerAPI(minerapi))
mux.Handle("/rpc/v0", rpcServer)
mux.PathPrefix("/remote").HandlerFunc(minerapi.(*impl.StorageMinerAPI).ServeRemote)
mux.PathPrefix("/").Handler(http.DefaultServeMux) // pprof
ah := &auth.Handler{
Verify: minerapi.AuthVerify,
Next: mux.ServeHTTP,
}
srv := &http.Server{Handler: ah}
sigChan := make(chan os.Signal, 2)
go func() {
select {
case <-sigChan:
case <-shutdownChan:
}
log.Warn("Shutting down...")
if err := stop(context.TODO()); err != nil {
log.Errorf("graceful shutting down failed: %s", err)
}
if err := srv.Shutdown(context.TODO()); err != nil {
log.Errorf("shutting down RPC server failed: %s", err)
}
log.Warn("Graceful shutdown successful")
}()
signal.Notify(sigChan, syscall.SIGTERM, syscall.SIGINT)
return srv.Serve(manet.NetListener(lst))
},
}