From 0a51a0a21933c6db1067b5bb598f4a0fe7b70051 Mon Sep 17 00:00:00 2001 From: Rod Vagg Date: Thu, 23 May 2024 15:42:43 +1000 Subject: [PATCH] feat!: build: separate miner and node version strings Ref: https://github.com/filecoin-project/lotus/issues/12010 --- api/docgen-openrpc/openrpc.go | 2 +- build/panic_reporter.go | 28 +++++++++++++++++++++++----- build/version.go | 23 ++++++++++++++++++----- chain/beacon/drand/drand.go | 2 +- cmd/lotus-bench/main.go | 2 +- cmd/lotus-fountain/main.go | 2 +- cmd/lotus-gateway/main.go | 2 +- cmd/lotus-health/main.go | 2 +- cmd/lotus-miner/main.go | 4 ++-- cmd/lotus-miner/run.go | 2 +- cmd/lotus-pcr/main.go | 2 +- cmd/lotus-seed/main.go | 2 +- cmd/lotus-shed/main.go | 2 +- cmd/lotus-stats/main.go | 2 +- cmd/lotus-wallet/main.go | 2 +- cmd/lotus-worker/main.go | 4 ++-- cmd/lotus/daemon.go | 2 +- cmd/lotus/main.go | 4 ++-- itests/api_test.go | 2 +- node/builder.go | 3 ++- node/builder_chain.go | 3 ++- node/builder_miner.go | 2 +- node/impl/common/common.go | 4 +++- node/impl/full/eth.go | 2 +- node/modules/lp2p/host.go | 4 ++-- 25 files changed, 72 insertions(+), 37 deletions(-) diff --git a/api/docgen-openrpc/openrpc.go b/api/docgen-openrpc/openrpc.go index c9504ba89..52e37aec6 100644 --- a/api/docgen-openrpc/openrpc.go +++ b/api/docgen-openrpc/openrpc.go @@ -106,7 +106,7 @@ func NewLotusOpenRPCDocument(Comments, GroupDocs map[string]string) *go_openrpc_ title := "Lotus RPC API" info.Title = (*meta_schema.InfoObjectProperties)(&title) - version := build.BuildVersion + version := build.NodeBuildVersion info.Version = (*meta_schema.InfoObjectVersion)(&version) return info }, diff --git a/build/panic_reporter.go b/build/panic_reporter.go index 617d619eb..7b40f8bc3 100644 --- a/build/panic_reporter.go +++ b/build/panic_reporter.go @@ -28,13 +28,31 @@ var PanicReportingPath = "panic-reports" // the lotus journal to be included in the panic report. var PanicReportJournalTail = defaultJournalTail -// GeneratePanicReport produces a timestamped dump of the application state +// GenerateNodePanicReport produces a timestamped dump of the application state // for inspection and debugging purposes. Call this function from any place // where a panic or severe error needs to be examined. `persistPath` is the // path where the reports should be saved. `repoPath` is the path where the // journal should be read from. `label` is an optional string to include // next to the report timestamp. -func GeneratePanicReport(persistPath, repoPath, label string) { +// +// This function should be called for panics originating from the Lotus daemon. +func GenerateNodePanicReport(persistPath, repoPath, label string) { + generatePanicReport(NodeUserVersion(), persistPath, repoPath, label) +} + +// GenerateMinerPanicReport produces a timestamped dump of the application state +// for inspection and debugging purposes. Call this function from any place +// where a panic or severe error needs to be examined. `persistPath` is the +// path where the reports should be saved. `repoPath` is the path where the +// journal should be read from. `label` is an optional string to include +// next to the report timestamp. +// +// This function should be called for panics originating from the Lotus miner. +func GenerateMinerPanicReport(persistPath, repoPath, label string) { + generatePanicReport(MinerUserVersion(), persistPath, repoPath, label) +} + +func generatePanicReport(buildVersion BuildVersion, persistPath, repoPath, label string) { // make sure we always dump the latest logs on the way out // especially since we're probably panicking defer panicLog.Sync() //nolint:errcheck @@ -64,21 +82,21 @@ func GeneratePanicReport(persistPath, repoPath, label string) { return } - writeAppVersion(filepath.Join(reportPath, "version")) + writeAppVersion(buildVersion, filepath.Join(reportPath, "version")) writeStackTrace(filepath.Join(reportPath, "stacktrace.dump")) writeProfile("goroutines", filepath.Join(reportPath, "goroutines.pprof.gz")) writeProfile("heap", filepath.Join(reportPath, "heap.pprof.gz")) writeJournalTail(PanicReportJournalTail, repoPath, filepath.Join(reportPath, "journal.ndjson")) } -func writeAppVersion(file string) { +func writeAppVersion(buildVersion BuildVersion, file string) { f, err := os.Create(file) if err != nil { panicLog.Error(err.Error()) } defer f.Close() //nolint:errcheck - versionString := []byte(BuildVersion + BuildTypeString() + CurrentCommit + "\n") + versionString := []byte(string(buildVersion) + BuildTypeString() + CurrentCommit + "\n") if _, err := f.Write(versionString); err != nil { panicLog.Error(err.Error()) } diff --git a/build/version.go b/build/version.go index 2244c98d8..4e8e24f30 100644 --- a/build/version.go +++ b/build/version.go @@ -2,6 +2,8 @@ package build import "os" +type BuildVersion string + var CurrentCommit string var BuildType int @@ -36,13 +38,24 @@ func BuildTypeString() string { } } -// BuildVersion is the local build version -const BuildVersion = "1.27.1-dev" +// NodeBuildVersion is the local build version of the Lotus daemon +const NodeBuildVersion string = "1.27.1-dev" -func UserVersion() string { +func NodeUserVersion() BuildVersion { if os.Getenv("LOTUS_VERSION_IGNORE_COMMIT") == "1" { - return BuildVersion + return BuildVersion(NodeBuildVersion) } - return BuildVersion + BuildTypeString() + CurrentCommit + return BuildVersion(NodeBuildVersion + BuildTypeString() + CurrentCommit) +} + +// MinerBuildVersion is the local build version of the Lotus miner +const MinerBuildVersion = "1.27.1-dev" + +func MinerUserVersion() BuildVersion { + if os.Getenv("LOTUS_VERSION_IGNORE_COMMIT") == "1" { + return BuildVersion(MinerBuildVersion) + } + + return BuildVersion(MinerBuildVersion + BuildTypeString() + CurrentCommit) } diff --git a/chain/beacon/drand/drand.go b/chain/beacon/drand/drand.go index 852a1a31c..1d781b057 100644 --- a/chain/beacon/drand/drand.go +++ b/chain/beacon/drand/drand.go @@ -97,7 +97,7 @@ func NewDrandBeacon(genesisTs, interval uint64, ps *pubsub.PubSub, config dtypes if err != nil { return nil, xerrors.Errorf("could not create http drand client: %w", err) } - hc.(DrandHTTPClient).SetUserAgent("drand-client-lotus/" + build.BuildVersion) + hc.(DrandHTTPClient).SetUserAgent("drand-client-lotus/" + build.NodeBuildVersion) clients = append(clients, hc) } diff --git a/cmd/lotus-bench/main.go b/cmd/lotus-bench/main.go index 1a7a0d087..8aa6768aa 100644 --- a/cmd/lotus-bench/main.go +++ b/cmd/lotus-bench/main.go @@ -100,7 +100,7 @@ func main() { app := &cli.App{ Name: "lotus-bench", Usage: "Benchmark performance of lotus on your hardware", - Version: build.UserVersion(), + Version: string(build.NodeUserVersion()), DisableSliceFlagSeparator: true, Commands: []*cli.Command{ proveCmd, diff --git a/cmd/lotus-fountain/main.go b/cmd/lotus-fountain/main.go index 36d5faf0c..191a91da4 100644 --- a/cmd/lotus-fountain/main.go +++ b/cmd/lotus-fountain/main.go @@ -41,7 +41,7 @@ func main() { app := &cli.App{ Name: "lotus-fountain", Usage: "Devnet token distribution utility", - Version: build.UserVersion(), + Version: string(build.NodeUserVersion()), Flags: []cli.Flag{ &cli.StringFlag{ Name: "repo", diff --git a/cmd/lotus-gateway/main.go b/cmd/lotus-gateway/main.go index 35a43e18b..2c5279ed4 100644 --- a/cmd/lotus-gateway/main.go +++ b/cmd/lotus-gateway/main.go @@ -40,7 +40,7 @@ func main() { app := &cli.App{ Name: "lotus-gateway", Usage: "Public API server for lotus", - Version: build.UserVersion(), + Version: string(build.NodeUserVersion()), Flags: []cli.Flag{ &cli.StringFlag{ Name: "repo", diff --git a/cmd/lotus-health/main.go b/cmd/lotus-health/main.go index 59c81e7c9..8e58624b6 100644 --- a/cmd/lotus-health/main.go +++ b/cmd/lotus-health/main.go @@ -36,7 +36,7 @@ func main() { app := &cli.App{ Name: "lotus-health", Usage: "Tools for monitoring lotus daemon health", - Version: build.UserVersion(), + Version: string(build.NodeUserVersion()), Commands: local, Flags: []cli.Flag{ &cli.StringFlag{ diff --git a/cmd/lotus-miner/main.go b/cmd/lotus-miner/main.go index 1fc7abfa8..3d292fb25 100644 --- a/cmd/lotus-miner/main.go +++ b/cmd/lotus-miner/main.go @@ -101,7 +101,7 @@ func main() { app := &cli.App{ Name: "lotus-miner", Usage: "Filecoin decentralized storage network miner", - Version: build.UserVersion(), + Version: string(build.MinerUserVersion()), EnableBashCompletion: true, Flags: []cli.Flag{ &cli.StringFlag{ @@ -159,7 +159,7 @@ func main() { After: func(c *cli.Context) error { if r := recover(); r != nil { // Generate report in LOTUS_PATH and re-raise panic - build.GeneratePanicReport(c.String("panic-reports"), c.String(FlagMinerRepo), c.App.Name) + build.GenerateMinerPanicReport(c.String("panic-reports"), c.String(FlagMinerRepo), c.App.Name) panic(r) } return nil diff --git a/cmd/lotus-miner/run.go b/cmd/lotus-miner/run.go index 93dfea2fc..15be2fbfd 100644 --- a/cmd/lotus-miner/run.go +++ b/cmd/lotus-miner/run.go @@ -57,7 +57,7 @@ var runCmd = &cli.Command{ } ctx, _ := tag.New(lcli.DaemonContext(cctx), - tag.Insert(metrics.Version, build.BuildVersion), + tag.Insert(metrics.Version, build.MinerBuildVersion), tag.Insert(metrics.Commit, build.CurrentCommit), tag.Insert(metrics.NodeType, "miner"), ) diff --git a/cmd/lotus-pcr/main.go b/cmd/lotus-pcr/main.go index 199810e03..a4a246f33 100644 --- a/cmd/lotus-pcr/main.go +++ b/cmd/lotus-pcr/main.go @@ -70,7 +70,7 @@ func main() { A single message will be produced per miner totaling their refund for all PreCommitSector messages in a tipset. `, - Version: build.UserVersion(), + Version: string(build.NodeUserVersion()), Flags: []cli.Flag{ &cli.StringFlag{ Name: "lotus-path", diff --git a/cmd/lotus-seed/main.go b/cmd/lotus-seed/main.go index 9deae560e..dd70cce21 100644 --- a/cmd/lotus-seed/main.go +++ b/cmd/lotus-seed/main.go @@ -38,7 +38,7 @@ func main() { app := &cli.App{ Name: "lotus-seed", Usage: "Seal sectors for genesis miner", - Version: build.UserVersion(), + Version: string(build.NodeUserVersion()), Flags: []cli.Flag{ &cli.StringFlag{ Name: "sector-dir", diff --git a/cmd/lotus-shed/main.go b/cmd/lotus-shed/main.go index 2b3b18670..f3f23f566 100644 --- a/cmd/lotus-shed/main.go +++ b/cmd/lotus-shed/main.go @@ -97,7 +97,7 @@ func main() { app := &cli.App{ Name: "lotus-shed", Usage: "A place for all the lotus tools", - Version: build.UserVersion(), + Version: string(build.NodeUserVersion()), Commands: local, Flags: []cli.Flag{ &cli.StringFlag{ diff --git a/cmd/lotus-stats/main.go b/cmd/lotus-stats/main.go index 20971c1f3..16c625952 100644 --- a/cmd/lotus-stats/main.go +++ b/cmd/lotus-stats/main.go @@ -42,7 +42,7 @@ func main() { app := &cli.App{ Name: "lotus-stats", Usage: "Collect basic information about a filecoin network using lotus", - Version: build.UserVersion(), + Version: string(build.NodeUserVersion()), Flags: []cli.Flag{ &cli.StringFlag{ Name: "lotus-path", diff --git a/cmd/lotus-wallet/main.go b/cmd/lotus-wallet/main.go index 8360dae15..84818ecb1 100644 --- a/cmd/lotus-wallet/main.go +++ b/cmd/lotus-wallet/main.go @@ -52,7 +52,7 @@ func main() { app := &cli.App{ Name: "lotus-wallet", Usage: "Basic external wallet", - Version: build.UserVersion(), + Version: string(build.NodeUserVersion()), Description: ` lotus-wallet provides a remote wallet service for lotus. diff --git a/cmd/lotus-worker/main.go b/cmd/lotus-worker/main.go index 41af11bdd..15283a30b 100644 --- a/cmd/lotus-worker/main.go +++ b/cmd/lotus-worker/main.go @@ -70,7 +70,7 @@ func main() { app := &cli.App{ Name: "lotus-worker", Usage: "Remote miner worker", - Version: build.UserVersion(), + Version: string(build.MinerUserVersion()), EnableBashCompletion: true, Flags: []cli.Flag{ &cli.StringFlag{ @@ -104,7 +104,7 @@ func main() { After: func(c *cli.Context) error { if r := recover(); r != nil { // Generate report in LOTUS_PANIC_REPORT_PATH and re-raise panic - build.GeneratePanicReport(c.String("panic-reports"), c.String(FlagWorkerRepo), c.App.Name) + build.GenerateMinerPanicReport(c.String("panic-reports"), c.String(FlagWorkerRepo), c.App.Name) panic(r) } return nil diff --git a/cmd/lotus/daemon.go b/cmd/lotus/daemon.go index 369938020..ba2936e2a 100644 --- a/cmd/lotus/daemon.go +++ b/cmd/lotus/daemon.go @@ -209,7 +209,7 @@ var DaemonCmd = &cli.Command{ } ctx, _ := tag.New(context.Background(), - tag.Insert(metrics.Version, build.BuildVersion), + tag.Insert(metrics.Version, build.NodeBuildVersion), tag.Insert(metrics.Commit, build.CurrentCommit), tag.Insert(metrics.NodeType, "chain"), ) diff --git a/cmd/lotus/main.go b/cmd/lotus/main.go index fce9a6136..6b29f6cf8 100644 --- a/cmd/lotus/main.go +++ b/cmd/lotus/main.go @@ -72,7 +72,7 @@ func main() { app := &cli.App{ Name: "lotus", Usage: "Filecoin decentralized storage network client", - Version: build.UserVersion(), + Version: string(build.NodeUserVersion()), EnableBashCompletion: true, Flags: []cli.Flag{ &cli.StringFlag{ @@ -107,7 +107,7 @@ func main() { After: func(c *cli.Context) error { if r := recover(); r != nil { // Generate report in LOTUS_PATH and re-raise panic - build.GeneratePanicReport(c.String("panic-reports"), c.String("repo"), c.App.Name) + build.GenerateNodePanicReport(c.String("panic-reports"), c.String("repo"), c.App.Name) panic(r) } return nil diff --git a/itests/api_test.go b/itests/api_test.go index ff43bd5c0..00994ee32 100644 --- a/itests/api_test.go +++ b/itests/api_test.go @@ -74,7 +74,7 @@ func (ts *apiSuite) testVersion(t *testing.T) { versions := strings.Split(v.Version, "+") require.NotZero(t, len(versions), "empty version") - require.Equal(t, versions[0], build.BuildVersion) + require.Equal(t, versions[0], build.NodeBuildVersion) } func (ts *apiSuite) testID(t *testing.T) { diff --git a/node/builder.go b/node/builder.go index 1cd4823d5..d827b8d38 100644 --- a/node/builder.go +++ b/node/builder.go @@ -266,12 +266,13 @@ func Base() Option { } // Config sets up constructors based on the provided Config -func ConfigCommon(cfg *config.Common, enableLibp2pNode bool) Option { +func ConfigCommon(cfg *config.Common, buildVersion build.BuildVersion, enableLibp2pNode bool) Option { // setup logging early lotuslog.SetLevelsFromConfig(cfg.Logging.SubsystemLevels) return Options( func(s *Settings) error { s.Config = true; return nil }, + Override(new(build.BuildVersion), buildVersion), Override(new(dtypes.APIEndpoint), func() (dtypes.APIEndpoint, error) { return multiaddr.NewMultiaddr(cfg.API.ListenAddress) }), diff --git a/node/builder_chain.go b/node/builder_chain.go index 0b40e4530..2e64e81a5 100644 --- a/node/builder_chain.go +++ b/node/builder_chain.go @@ -12,6 +12,7 @@ import ( "github.com/filecoin-project/go-fil-markets/storagemarket" "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain" "github.com/filecoin-project/lotus/chain/beacon" "github.com/filecoin-project/lotus/chain/consensus" @@ -184,7 +185,7 @@ func ConfigFullNode(c interface{}) Option { enableLibp2pNode := true // always enable libp2p for full nodes return Options( - ConfigCommon(&cfg.Common, enableLibp2pNode), + ConfigCommon(&cfg.Common, build.NodeUserVersion(), enableLibp2pNode), Override(new(dtypes.UniversalBlockstore), modules.UniversalBlockstore), diff --git a/node/builder_miner.go b/node/builder_miner.go index 08c71ba19..2b3f6ec2a 100644 --- a/node/builder_miner.go +++ b/node/builder_miner.go @@ -84,7 +84,7 @@ func ConfigStorageMiner(c interface{}) Option { Override(new(dtypes.DrandSchedule), modules.BuiltinDrandConfig), Override(new(dtypes.BootstrapPeers), modules.BuiltinBootstrap), Override(new(dtypes.DrandBootstrap), modules.DrandBootstrap), - ConfigCommon(&cfg.Common, enableLibp2pNode), + ConfigCommon(&cfg.Common, build.NodeUserVersion(), enableLibp2pNode), Override(CheckFDLimit, modules.CheckFdLimit(build.MinerFDLimit)), // recommend at least 100k FD limit to miners diff --git a/node/impl/common/common.go b/node/impl/common/common.go index eff6b58b8..5c4dd6a7f 100644 --- a/node/impl/common/common.go +++ b/node/impl/common/common.go @@ -24,6 +24,8 @@ var session = uuid.New() type CommonAPI struct { fx.In + BuildVersion build.BuildVersion + Alerting *alerting.Alerting APISecret *dtypes.APIAlg ShutdownChan dtypes.ShutdownChan @@ -63,7 +65,7 @@ func (a *CommonAPI) Version(context.Context) (api.APIVersion, error) { } return api.APIVersion{ - Version: build.UserVersion(), + Version: string(a.BuildVersion), APIVersion: v, BlockDelay: build.BlockDelaySecs, diff --git a/node/impl/full/eth.go b/node/impl/full/eth.go index e7aeafa90..b9fcdb8e8 100644 --- a/node/impl/full/eth.go +++ b/node/impl/full/eth.go @@ -836,7 +836,7 @@ func (a *EthModule) EthSendRawTransaction(ctx context.Context, rawTx ethtypes.Et } func (a *EthModule) Web3ClientVersion(ctx context.Context) (string, error) { - return build.UserVersion(), nil + return string(build.NodeUserVersion()), nil } func (a *EthModule) EthTraceBlock(ctx context.Context, blkNum string) ([]*ethtypes.EthTraceBlock, error) { diff --git a/node/modules/lp2p/host.go b/node/modules/lp2p/host.go index 9c140b41e..405bb8692 100644 --- a/node/modules/lp2p/host.go +++ b/node/modules/lp2p/host.go @@ -38,7 +38,7 @@ func Peerstore() (peerstore.Peerstore, error) { return pstoremem.NewPeerstore() } -func Host(mctx helpers.MetricsCtx, lc fx.Lifecycle, params P2PHostIn) (RawHost, error) { +func Host(mctx helpers.MetricsCtx, buildVersion build.BuildVersion, lc fx.Lifecycle, params P2PHostIn) (RawHost, error) { pkey := params.Peerstore.PrivKey(params.ID) if pkey == nil { return nil, fmt.Errorf("missing private key for node ID: %s", params.ID) @@ -49,7 +49,7 @@ func Host(mctx helpers.MetricsCtx, lc fx.Lifecycle, params P2PHostIn) (RawHost, libp2p.Peerstore(params.Peerstore), libp2p.NoListenAddrs, libp2p.Ping(true), - libp2p.UserAgent("lotus-" + build.UserVersion()), + libp2p.UserAgent("lotus-" + string(buildVersion)), } for _, o := range params.Opts { opts = append(opts, o...)