From a377033d22c67457457b2244d857b2ffbde53198 Mon Sep 17 00:00:00 2001 From: "Andrew Jackson (Ajax)" Date: Tue, 19 Sep 2023 22:48:39 -0500 Subject: [PATCH 01/15] config --- cmd/lotus-provider/config.go | 152 +++++++++++++++++++++---- cmd/lotus-provider/main.go | 32 +++++- cmd/lotus-provider/run.go | 58 +++------- go.mod | 3 + go.sum | 2 + lib/harmony/harmonydb/sql/20230919.sql | 5 + node/config/def.go | 43 +++++++ node/config/types.go | 39 +++++++ 8 files changed, 271 insertions(+), 63 deletions(-) create mode 100644 lib/harmony/harmonydb/sql/20230919.sql diff --git a/cmd/lotus-provider/config.go b/cmd/lotus-provider/config.go index b7a4c817a..c6e21599e 100644 --- a/cmd/lotus-provider/config.go +++ b/cmd/lotus-provider/config.go @@ -1,24 +1,35 @@ package main import ( + "context" + "errors" "fmt" + "os" + "regexp" + "strings" + "github.com/BurntSushi/toml" + "github.com/filecoin-project/lotus/lib/harmony/harmonydb" + "github.com/filecoin-project/lotus/node/config" + "github.com/kr/pretty" "github.com/urfave/cli/v2" ) var configCmd = &cli.Command{ Name: "config", - Usage: "Manage node config", + Usage: "Manage node config by layers. The layer 'base' will always be applied. ", Subcommands: []*cli.Command{ configDefaultCmd, configSetCmd, configGetCmd, + configListCmd, + configViewCmd, }, } var configDefaultCmd = &cli.Command{ Name: "default", - Usage: "Print default system config", + Usage: "Print default node config", Flags: []cli.Flag{ &cli.BoolFlag{ Name: "no-comment", @@ -26,36 +37,137 @@ var configDefaultCmd = &cli.Command{ }, }, Action: func(cctx *cli.Context) error { - fmt.Println("[config]\nstatus = Coming Soon") - // [overlay.sealer1.tasks]\nsealer_task_enable = true + c := config.DefaultLotusProvider() + + cb, err := config.ConfigUpdate(c, nil, config.Commented(!cctx.Bool("no-comment")), config.DefaultKeepUncommented()) + if err != nil { + return err + } + + fmt.Println(string(cb)) + return nil }, } var configSetCmd = &cli.Command{ - Name: "set", - Usage: "Set all config", + Name: "set", + Usage: "Set a config layer or the base", + ArgsUsage: "a layer's name", Action: func(cctx *cli.Context) error { - fmt.Println("Coming soon") + args := cctx.Args() + if args.Len() != 1 { + return errors.New("Must have exactly 1 arg for the file name.") + } + db, err := makeDB(cctx) + if err != nil { + return err + } + + fn := args.First() + bytes, err := os.ReadFile(fn) + if err != nil { + return fmt.Errorf("cannot read file %w", err) + } + + lp := config.DefaultLotusProvider() // ensure it's toml + toml.Decode(string(bytes), lp) + _ = lp + + name := strings.Split(fn, ".")[0] + _, err = db.Exec(context.Background(), + `INSERT INTO harmony_config (title, config) VALUES (?,?) + ON CONFLICT (title) DO UPDATE SET config = excluded.config`, name, string(bytes)) + if err != nil { + return fmt.Errorf("unable to save config layer: %w", err) + } + + fmt.Println("Layer " + name + " created/updated") return nil }, } var configGetCmd = &cli.Command{ - Name: "get", - Usage: "Get all config", - Flags: []cli.Flag{ - &cli.BoolFlag{ - Name: "no-comment", - Usage: "don't comment default values", - }, - &cli.BoolFlag{ - Name: "no-doc", - Usage: "don't add value documentation", - }, - }, + Name: "get", + Usage: "Get a config layer by name. You may want to pipe the output to a file, or use 'less'", + ArgsUsage: "layer name", Action: func(cctx *cli.Context) error { - fmt.Println("Coming soon") + args := cctx.Args() + if args.Len() != 1 { + return errors.New("Must have exactly 1 arg for the layer name.") + } + db, err := makeDB(cctx) + if err != nil { + return err + } + + var cfg string + err = db.QueryRow(context.Background(), `SELECT config FROM harmony_config WHERE title=?`, args.First()).Scan(&cfg) + if err != nil { + return err + } + fmt.Println(cfg) + return nil }, } + +var configListCmd = &cli.Command{ + Name: "list", + Usage: "List config layers you can get.", + Flags: []cli.Flag{}, + Action: func(cctx *cli.Context) error { + db, err := makeDB(cctx) + if err != nil { + return err + } + var res []string + db.Select(context.Background(), &res, `SELECT title FROM harmony_confg ORDER BY title`) + for _, r := range res { + fmt.Println(r) + } + + return nil + }, +} + +var configViewCmd = &cli.Command{ + Name: "view", + Usage: "View stacked config layers as it will be interpreted.", + ArgsUsage: "a list of layers to be interpreted as the final config", + Action: func(cctx *cli.Context) error { + db, err := makeDB(cctx) + if err != nil { + return err + } + lp, err := getConfig(cctx, db) + if err != nil { + return err + } + + fmt.Println(pretty.Sprint(lp)) + + return nil + }, +} + +func getConfig(cctx *cli.Context, db *harmonydb.DB) (*config.LotusProviderConfig, error) { + lp := config.DefaultLotusProvider() + have := []string{} + for _, layer := range regexp.MustCompile("[ |,]").Split(cctx.String("layers"), -1) { + text := "" + err := db.QueryRow(cctx.Context, `SELECT config FROM harmony_config WHERE title=?`, layer).Scan(&text) + if err != nil { + return nil, fmt.Errorf("could not read layer %s: %w", layer, err) + } + meta, err := toml.Decode(text, &lp) + if err != nil { + return nil, fmt.Errorf("could not read layer, bad toml %s: %w", layer, err) + } + for _, k := range meta.Keys() { + have = append(have, strings.Join(k, " ")) + } + } + _ = have // TODO: verify that required fields are here. + return lp, nil +} diff --git a/cmd/lotus-provider/main.go b/cmd/lotus-provider/main.go index 380923b07..aa53251e5 100644 --- a/cmd/lotus-provider/main.go +++ b/cmd/lotus-provider/main.go @@ -81,10 +81,36 @@ func main() { Value: "~/.lotusprovider", // should follow --repo default }, &cli.StringFlag{ - Name: "repo", - EnvVars: []string{"LOTUS_PATH"}, + Name: "db-host", + EnvVars: []string{"LOTUS_DB_HOST"}, + Usage: "Command separated list of hostnames for yugabyte cluster", + Value: "yugabyte", + }, + &cli.StringFlag{ + Name: "db-name", + EnvVars: []string{"LOTUS_DB_NAME"}, + Value: "yugabyte", + }, + &cli.StringFlag{ + Name: "db-user", + EnvVars: []string{"LOTUS_DB_USER"}, + Value: "yugabyte", + }, + &cli.StringFlag{ + Name: "db-password", + EnvVars: []string{"LOTUS_DB_PASSWORD"}, + Value: "yugabyte", + }, + &cli.StringFlag{ + Name: "db-port", + EnvVars: []string{"LOTUS_DB_PORT"}, Hidden: true, - Value: "~/.lotus", + Value: "5433", + }, + &cli.StringFlag{ + Name: "layers", + EnvVars: []string{"LOTUS_LAYERS"}, + Value: "base", }, cliutil.FlagVeryVerbose, }, diff --git a/cmd/lotus-provider/run.go b/cmd/lotus-provider/run.go index 45fbfcd95..95e5cf346 100644 --- a/cmd/lotus-provider/run.go +++ b/cmd/lotus-provider/run.go @@ -54,37 +54,6 @@ var runCmd = &cli.Command{ Usage: "manage open file limit", Value: true, }, - &cli.StringFlag{ - Name: "db-host", - EnvVars: []string{"LOTUS_DB_HOST"}, - Usage: "Command separated list of hostnames for yugabyte cluster", - Value: "yugabyte", - }, - &cli.StringFlag{ - Name: "db-name", - EnvVars: []string{"LOTUS_DB_NAME"}, - Value: "yugabyte", - }, - &cli.StringFlag{ - Name: "db-user", - EnvVars: []string{"LOTUS_DB_USER"}, - Value: "yugabyte", - }, - &cli.StringFlag{ - Name: "db-password", - EnvVars: []string{"LOTUS_DB_PASSWORD"}, - Value: "yugabyte", - }, - &cli.StringFlag{ - Name: "db-port", - EnvVars: []string{"LOTUS_DB_PORT"}, - Hidden: true, - Value: "5433", - }, - &cli.StringFlag{ - Name: FlagProviderRepo, - Value: "~/lotusminer", - }, }, Action: func(cctx *cli.Context) error { if !cctx.Bool("enable-gpu-proving") { @@ -159,18 +128,10 @@ var runCmd = &cli.Command{ } } - dbConfig := config.HarmonyDB{ - Username: cctx.String("db-user"), - Password: cctx.String("db-password"), - Hosts: strings.Split(cctx.String("db-host"), ","), - Database: cctx.String("db-name"), - Port: cctx.String("db-port"), - } - db, err := harmonydb.NewFromConfig(dbConfig) + db, err := makeDB(cctx) if err != nil { return err } - shutdownChan := make(chan struct{}) /* defaults break lockedRepo (below) @@ -209,6 +170,11 @@ var runCmd = &cli.Command{ if err != nil { return err } + lp, err := getConfig(cctx, db) + if err != nil { + return err + } + _ = lp // here is where the config feeds into task runners taskEngine, err := harmonytask.New(db, []harmonytask.TaskInterface{}, address) if err != nil { @@ -256,3 +222,15 @@ var runCmd = &cli.Command{ return nil }, } + +func makeDB(cctx *cli.Context) (*harmonydb.DB, error) { + dbConfig := config.HarmonyDB{ + Username: cctx.String("db-user"), + Password: cctx.String("db-password"), + Hosts: strings.Split(cctx.String("db-host"), ","), + Database: cctx.String("db-name"), + Port: cctx.String("db-port"), + } + return harmonydb.NewFromConfig(dbConfig) + +} diff --git a/go.mod b/go.mod index ac0950eed..ee89a61f3 100644 --- a/go.mod +++ b/go.mod @@ -273,6 +273,8 @@ require ( github.com/klauspost/compress v1.16.5 // indirect github.com/klauspost/cpuid/v2 v2.2.5 // indirect github.com/koron/go-ssdp v0.0.4 // indirect + github.com/kr/pretty v0.3.1 // indirect + github.com/kr/text v0.2.0 // indirect github.com/leodido/go-urn v1.2.4 // indirect github.com/libp2p/go-cidranger v1.1.0 // indirect github.com/libp2p/go-flow-metrics v0.1.0 // indirect @@ -320,6 +322,7 @@ require ( github.com/quic-go/quic-go v0.33.0 // indirect github.com/quic-go/webtransport-go v0.5.3 // indirect github.com/rivo/uniseg v0.1.0 // indirect + github.com/rogpeppe/go-internal v1.9.0 // indirect github.com/rs/cors v1.7.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/shirou/gopsutil v2.18.12+incompatible // indirect diff --git a/go.sum b/go.sum index 5fb7cda2d..db80d2f3c 100644 --- a/go.sum +++ b/go.sum @@ -984,6 +984,7 @@ github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfn github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= @@ -1531,6 +1532,7 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= diff --git a/lib/harmony/harmonydb/sql/20230919.sql b/lib/harmony/harmonydb/sql/20230919.sql new file mode 100644 index 000000000..84699a0d5 --- /dev/null +++ b/lib/harmony/harmonydb/sql/20230919.sql @@ -0,0 +1,5 @@ +CREATE TABLE harmony_config ( + id SERIAL PRIMARY KEY NOT NULL, + title VARCHAR(300) UNIQUE NOT NULL, + config TEXT NOT NULL +); \ No newline at end of file diff --git a/node/config/def.go b/node/config/def.go index aba7e340d..0b77a56f0 100644 --- a/node/config/def.go +++ b/node/config/def.go @@ -343,3 +343,46 @@ func DefaultUserRaftConfig() *UserRaftConfig { return &cfg } + +func DefaultLotusProvider() *LotusProviderConfig { + /* + reqs := map[string]*regexp.Regexp{} + for _, str := range LotusRequired { + reqs[str]=regexp.MustCompile("(?i)"+str) + } + */ + return &LotusProviderConfig{ + Fees: LotusProviderFees{ + DefaultMaxFee: DefaultDefaultMaxFee, + MaxPreCommitGasFee: types.MustParseFIL("0.025"), + MaxCommitGasFee: types.MustParseFIL("0.05"), + + MaxPreCommitBatchGasFee: BatchFeeConfig{ + Base: types.MustParseFIL("0"), + PerSector: types.MustParseFIL("0.02"), + }, + MaxCommitBatchGasFee: BatchFeeConfig{ + Base: types.MustParseFIL("0"), + PerSector: types.MustParseFIL("0.03"), // enough for 6 agg and 1nFIL base fee + }, + + MaxTerminateGasFee: types.MustParseFIL("0.5"), + MaxWindowPoStGasFee: types.MustParseFIL("5"), + MaxPublishDealsFee: types.MustParseFIL("0.05"), + }, + Addresses: LotusProviderAddresses{ + PreCommitControl: []string{}, + CommitControl: []string{}, + TerminateControl: []string{}, + }, + /* + HarmonyDB: HarmonyDB{ + Hosts: []string{"127.0.0.1"}, + Username: "yugabyte", + Password: "yugabyte", + Database: "yugabyte", + Port: "5433", + }, + */ + } +} diff --git a/node/config/types.go b/node/config/types.go index 21c92e47b..282f35037 100644 --- a/node/config/types.go +++ b/node/config/types.go @@ -65,6 +65,14 @@ type StorageMiner struct { HarmonyDB HarmonyDB } +type LotusProviderConfig struct { + EnableWindowPost bool + EnableWinningPost bool + + Fees LotusProviderFees + Addresses LotusProviderAddresses +} + type DAGStoreConfig struct { // Path to the dagstore root directory. This directory contains three // subdirectories, which can be symlinked to alternative locations if @@ -499,6 +507,20 @@ type MinerFeeConfig struct { MaxMarketBalanceAddFee types.FIL } +type LotusProviderFees struct { + DefaultMaxFee types.FIL + MaxPreCommitGasFee types.FIL + MaxCommitGasFee types.FIL + + // maxBatchFee = maxBase + maxPerSector * nSectors + MaxPreCommitBatchGasFee BatchFeeConfig + MaxCommitBatchGasFee BatchFeeConfig + + MaxTerminateGasFee types.FIL + // WindowPoSt is a high-value operation, so the default fee should be high. + MaxWindowPoStGasFee types.FIL + MaxPublishDealsFee types.FIL +} type MinerAddressConfig struct { // Addresses to send PreCommit messages from PreCommitControl []string @@ -517,6 +539,23 @@ type MinerAddressConfig struct { DisableWorkerFallback bool } +type LotusProviderAddresses struct { + // Addresses to send PreCommit messages from + PreCommitControl []string + // Addresses to send Commit messages from + CommitControl []string + TerminateControl []string + + // DisableOwnerFallback disables usage of the owner address for messages + // sent automatically + DisableOwnerFallback bool + // DisableWorkerFallback disables usage of the worker address for messages + // sent automatically, if control addresses are configured. + // A control address that doesn't have enough funds will still be chosen + // over the worker address if this flag is set. + DisableWorkerFallback bool +} + // API contains configs for API endpoint type API struct { // Binding address for the Lotus API From 144bc9fcead832ea9e54a023725716ba8c97cf2d Mon Sep 17 00:00:00 2001 From: "Andrew Jackson (Ajax)" Date: Wed, 20 Sep 2023 12:58:56 -0500 Subject: [PATCH 02/15] lint for config pr --- cmd/lotus-provider/config.go | 19 +++++++++++++------ go.mod | 2 +- node/config/types.go | 1 + 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/cmd/lotus-provider/config.go b/cmd/lotus-provider/config.go index c6e21599e..85b395469 100644 --- a/cmd/lotus-provider/config.go +++ b/cmd/lotus-provider/config.go @@ -9,10 +9,11 @@ import ( "strings" "github.com/BurntSushi/toml" - "github.com/filecoin-project/lotus/lib/harmony/harmonydb" - "github.com/filecoin-project/lotus/node/config" "github.com/kr/pretty" "github.com/urfave/cli/v2" + + "github.com/filecoin-project/lotus/lib/harmony/harmonydb" + "github.com/filecoin-project/lotus/node/config" ) var configCmd = &cli.Command{ @@ -57,7 +58,7 @@ var configSetCmd = &cli.Command{ Action: func(cctx *cli.Context) error { args := cctx.Args() if args.Len() != 1 { - return errors.New("Must have exactly 1 arg for the file name.") + return errors.New("must have exactly 1 arg for the file name") } db, err := makeDB(cctx) if err != nil { @@ -71,7 +72,10 @@ var configSetCmd = &cli.Command{ } lp := config.DefaultLotusProvider() // ensure it's toml - toml.Decode(string(bytes), lp) + _, err = toml.Decode(string(bytes), lp) + if err != nil { + return fmt.Errorf("cannot decode file: %w", err) + } _ = lp name := strings.Split(fn, ".")[0] @@ -94,7 +98,7 @@ var configGetCmd = &cli.Command{ Action: func(cctx *cli.Context) error { args := cctx.Args() if args.Len() != 1 { - return errors.New("Must have exactly 1 arg for the layer name.") + return fmt.Errorf("want 1 layer arg, got %d", args.Len()) } db, err := makeDB(cctx) if err != nil { @@ -122,7 +126,10 @@ var configListCmd = &cli.Command{ return err } var res []string - db.Select(context.Background(), &res, `SELECT title FROM harmony_confg ORDER BY title`) + err = db.Select(context.Background(), &res, `SELECT title FROM harmony_confg ORDER BY title`) + if err != nil { + return fmt.Errorf("unable to read from db: %w", err) + } for _, r := range res { fmt.Println(r) } diff --git a/go.mod b/go.mod index ee89a61f3..666481a8f 100644 --- a/go.mod +++ b/go.mod @@ -108,6 +108,7 @@ require ( github.com/jackc/pgx/v5 v5.4.1 github.com/kelseyhightower/envconfig v1.4.0 github.com/koalacxr/quantile v0.0.1 + github.com/kr/pretty v0.3.1 github.com/libp2p/go-buffer-pool v0.1.0 github.com/libp2p/go-libp2p v0.27.6 github.com/libp2p/go-libp2p-consensus v0.0.1 @@ -273,7 +274,6 @@ require ( github.com/klauspost/compress v1.16.5 // indirect github.com/klauspost/cpuid/v2 v2.2.5 // indirect github.com/koron/go-ssdp v0.0.4 // indirect - github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect github.com/leodido/go-urn v1.2.4 // indirect github.com/libp2p/go-cidranger v1.1.0 // indirect diff --git a/node/config/types.go b/node/config/types.go index 282f35037..346377fbc 100644 --- a/node/config/types.go +++ b/node/config/types.go @@ -71,6 +71,7 @@ type LotusProviderConfig struct { Fees LotusProviderFees Addresses LotusProviderAddresses + Proving ProvingConfig } type DAGStoreConfig struct { From 456ead411b9d453188397b323f559c4a5c1b150a Mon Sep 17 00:00:00 2001 From: "Andrew Jackson (Ajax)" Date: Wed, 20 Sep 2023 16:11:14 -0500 Subject: [PATCH 03/15] docsgen --- node/config/doc_gen.go | 118 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) diff --git a/node/config/doc_gen.go b/node/config/doc_gen.go index 9c19d1953..fc9e35623 100644 --- a/node/config/doc_gen.go +++ b/node/config/doc_gen.go @@ -630,6 +630,124 @@ closed by the connection manager.`, Comment: `SubsystemLevels specify per-subsystem log levels`, }, }, + "LotusProviderAddresses": []DocField{ + { + Name: "PreCommitControl", + Type: "[]string", + + Comment: `Addresses to send PreCommit messages from`, + }, + { + Name: "CommitControl", + Type: "[]string", + + Comment: `Addresses to send Commit messages from`, + }, + { + Name: "TerminateControl", + Type: "[]string", + + Comment: ``, + }, + { + Name: "DisableOwnerFallback", + Type: "bool", + + Comment: `DisableOwnerFallback disables usage of the owner address for messages +sent automatically`, + }, + { + Name: "DisableWorkerFallback", + Type: "bool", + + Comment: `DisableWorkerFallback disables usage of the worker address for messages +sent automatically, if control addresses are configured. +A control address that doesn't have enough funds will still be chosen +over the worker address if this flag is set.`, + }, + }, + "LotusProviderConfig": []DocField{ + { + Name: "EnableWindowPost", + Type: "bool", + + Comment: ``, + }, + { + Name: "EnableWinningPost", + Type: "bool", + + Comment: ``, + }, + { + Name: "Fees", + Type: "LotusProviderFees", + + Comment: ``, + }, + { + Name: "Addresses", + Type: "LotusProviderAddresses", + + Comment: ``, + }, + { + Name: "Proving", + Type: "ProvingConfig", + + Comment: ``, + }, + }, + "LotusProviderFees": []DocField{ + { + Name: "DefaultMaxFee", + Type: "types.FIL", + + Comment: ``, + }, + { + Name: "MaxPreCommitGasFee", + Type: "types.FIL", + + Comment: ``, + }, + { + Name: "MaxCommitGasFee", + Type: "types.FIL", + + Comment: ``, + }, + { + Name: "MaxPreCommitBatchGasFee", + Type: "BatchFeeConfig", + + Comment: `maxBatchFee = maxBase + maxPerSector * nSectors`, + }, + { + Name: "MaxCommitBatchGasFee", + Type: "BatchFeeConfig", + + Comment: ``, + }, + { + Name: "MaxTerminateGasFee", + Type: "types.FIL", + + Comment: ``, + }, + { + Name: "MaxWindowPoStGasFee", + Type: "types.FIL", + + Comment: `WindowPoSt is a high-value operation, so the default fee should be high.`, + }, + { + Name: "MaxPublishDealsFee", + Type: "types.FIL", + + Comment: ``, + }, + }, "MinerAddressConfig": []DocField{ { Name: "PreCommitControl", From 403c6e23e1e139af57c7bdd813ccc3ead8d49594 Mon Sep 17 00:00:00 2001 From: "Andrew Jackson (Ajax)" Date: Wed, 20 Sep 2023 16:17:51 -0500 Subject: [PATCH 04/15] lotusprovider docsgen2 --- cmd/lotus-provider/config.go | 4 +- .../en/default-lotus-provider-config.toml | 189 ++++++++++++++++++ node/config/load.go | 12 +- 3 files changed, 202 insertions(+), 3 deletions(-) create mode 100644 documentation/en/default-lotus-provider-config.toml diff --git a/cmd/lotus-provider/config.go b/cmd/lotus-provider/config.go index 85b395469..650843aa7 100644 --- a/cmd/lotus-provider/config.go +++ b/cmd/lotus-provider/config.go @@ -40,12 +40,12 @@ var configDefaultCmd = &cli.Command{ Action: func(cctx *cli.Context) error { c := config.DefaultLotusProvider() - cb, err := config.ConfigUpdate(c, nil, config.Commented(!cctx.Bool("no-comment")), config.DefaultKeepUncommented()) + cb, err := config.ConfigUpdate(c, nil, config.Commented(!cctx.Bool("no-comment")), config.DefaultKeepUncommented(), config.NoEnv()) if err != nil { return err } - fmt.Println(string(cb)) + fmt.Print(string(cb)) return nil }, diff --git a/documentation/en/default-lotus-provider-config.toml b/documentation/en/default-lotus-provider-config.toml new file mode 100644 index 000000000..566a0859d --- /dev/null +++ b/documentation/en/default-lotus-provider-config.toml @@ -0,0 +1,189 @@ +# type: bool +#EnableWindowPost = false + +# type: bool +#EnableWinningPost = false + + +[Fees] + # type: types.FIL + #DefaultMaxFee = "0.07 FIL" + + # type: types.FIL + #MaxPreCommitGasFee = "0.025 FIL" + + # type: types.FIL + #MaxCommitGasFee = "0.05 FIL" + + # type: types.FIL + #MaxTerminateGasFee = "0.5 FIL" + + # WindowPoSt is a high-value operation, so the default fee should be high. + # + # type: types.FIL + #MaxWindowPoStGasFee = "5 FIL" + + # type: types.FIL + #MaxPublishDealsFee = "0.05 FIL" + + [Fees.MaxPreCommitBatchGasFee] + # type: types.FIL + #Base = "0 FIL" + + # type: types.FIL + #PerSector = "0.02 FIL" + + [Fees.MaxCommitBatchGasFee] + # type: types.FIL + #Base = "0 FIL" + + # type: types.FIL + #PerSector = "0.03 FIL" + + +[Addresses] + # Addresses to send PreCommit messages from + # + # type: []string + #PreCommitControl = [] + + # Addresses to send Commit messages from + # + # type: []string + #CommitControl = [] + + # type: []string + #TerminateControl = [] + + # DisableOwnerFallback disables usage of the owner address for messages + # sent automatically + # + # type: bool + #DisableOwnerFallback = false + + # DisableWorkerFallback disables usage of the worker address for messages + # sent automatically, if control addresses are configured. + # A control address that doesn't have enough funds will still be chosen + # over the worker address if this flag is set. + # + # type: bool + #DisableWorkerFallback = false + + +[Proving] + # Maximum number of sector checks to run in parallel. (0 = unlimited) + # + # WARNING: Setting this value too high may make the node crash by running out of stack + # WARNING: Setting this value too low may make sector challenge reading much slower, resulting in failed PoSt due + # to late submission. + # + # After changing this option, confirm that the new value works in your setup by invoking + # 'lotus-miner proving compute window-post 0' + # + # type: int + #ParallelCheckLimit = 0 + + # Maximum amount of time a proving pre-check can take for a sector. If the check times out the sector will be skipped + # + # WARNING: Setting this value too low risks in sectors being skipped even though they are accessible, just reading the + # test challenge took longer than this timeout + # WARNING: Setting this value too high risks missing PoSt deadline in case IO operations related to this sector are + # blocked (e.g. in case of disconnected NFS mount) + # + # type: Duration + #SingleCheckTimeout = "0s" + + # Maximum amount of time a proving pre-check can take for an entire partition. If the check times out, sectors in + # the partition which didn't get checked on time will be skipped + # + # WARNING: Setting this value too low risks in sectors being skipped even though they are accessible, just reading the + # test challenge took longer than this timeout + # WARNING: Setting this value too high risks missing PoSt deadline in case IO operations related to this partition are + # blocked or slow + # + # type: Duration + #PartitionCheckTimeout = "0s" + + # Disable Window PoSt computation on the lotus-miner process even if no window PoSt workers are present. + # + # WARNING: If no windowPoSt workers are connected, window PoSt WILL FAIL resulting in faulty sectors which will need + # to be recovered. Before enabling this option, make sure your PoSt workers work correctly. + # + # After changing this option, confirm that the new value works in your setup by invoking + # 'lotus-miner proving compute window-post 0' + # + # type: bool + #DisableBuiltinWindowPoSt = false + + # Disable Winning PoSt computation on the lotus-miner process even if no winning PoSt workers are present. + # + # WARNING: If no WinningPoSt workers are connected, Winning PoSt WILL FAIL resulting in lost block rewards. + # Before enabling this option, make sure your PoSt workers work correctly. + # + # type: bool + #DisableBuiltinWinningPoSt = false + + # Disable WindowPoSt provable sector readability checks. + # + # In normal operation, when preparing to compute WindowPoSt, lotus-miner will perform a round of reading challenges + # from all sectors to confirm that those sectors can be proven. Challenges read in this process are discarded, as + # we're only interested in checking that sector data can be read. + # + # When using builtin proof computation (no PoSt workers, and DisableBuiltinWindowPoSt is set to false), this process + # can save a lot of time and compute resources in the case that some sectors are not readable - this is caused by + # the builtin logic not skipping snark computation when some sectors need to be skipped. + # + # When using PoSt workers, this process is mostly redundant, with PoSt workers challenges will be read once, and + # if challenges for some sectors aren't readable, those sectors will just get skipped. + # + # Disabling sector pre-checks will slightly reduce IO load when proving sectors, possibly resulting in shorter + # time to produce window PoSt. In setups with good IO capabilities the effect of this option on proving time should + # be negligible. + # + # NOTE: It likely is a bad idea to disable sector pre-checks in setups with no PoSt workers. + # + # NOTE: Even when this option is enabled, recovering sectors will be checked before recovery declaration message is + # sent to the chain + # + # After changing this option, confirm that the new value works in your setup by invoking + # 'lotus-miner proving compute window-post 0' + # + # type: bool + #DisableWDPoStPreChecks = false + + # Maximum number of partitions to prove in a single SubmitWindowPoSt messace. 0 = network limit (10 in nv16) + # + # A single partition may contain up to 2349 32GiB sectors, or 2300 64GiB sectors. + # + # The maximum number of sectors which can be proven in a single PoSt message is 25000 in network version 16, which + # means that a single message can prove at most 10 partitions + # + # Note that setting this value lower may result in less efficient gas use - more messages will be sent, + # to prove each deadline, resulting in more total gas use (but each message will have lower gas limit) + # + # Setting this value above the network limit has no effect + # + # type: int + #MaxPartitionsPerPoStMessage = 0 + + # In some cases when submitting DeclareFaultsRecovered messages, + # there may be too many recoveries to fit in a BlockGasLimit. + # In those cases it may be necessary to set this value to something low (eg 1); + # Note that setting this value lower may result in less efficient gas use - more messages will be sent than needed, + # resulting in more total gas use (but each message will have lower gas limit) + # + # type: int + #MaxPartitionsPerRecoveryMessage = 0 + + # Enable single partition per PoSt Message for partitions containing recovery sectors + # + # In cases when submitting PoSt messages which contain recovering sectors, the default network limit may still be + # too high to fit in the block gas limit. In those cases, it becomes useful to only house the single partition + # with recovering sectors in the post message + # + # Note that setting this value lower may result in less efficient gas use - more messages will be sent, + # to prove each deadline, resulting in more total gas use (but each message will have lower gas limit) + # + # type: bool + #SingleRecoveringPartitionPerPostMessage = false + diff --git a/node/config/load.go b/node/config/load.go index 913350912..fd015d533 100644 --- a/node/config/load.go +++ b/node/config/load.go @@ -124,6 +124,7 @@ func ValidateSplitstoreSet(cfgRaw string) error { type cfgUpdateOpts struct { comment bool keepUncommented func(string) bool + noEnv bool } // UpdateCfgOpt is a functional option for updating the config @@ -149,6 +150,13 @@ func DefaultKeepUncommented() UpdateCfgOpt { return KeepUncommented(MatchEnableSplitstoreField) } +func NoEnv() UpdateCfgOpt { + return func(opts *cfgUpdateOpts) error { + opts.noEnv = true + return nil + } +} + // ConfigUpdate takes in a config and a default config and optionally comments out default values func ConfigUpdate(cfgCur, cfgDef interface{}, opts ...UpdateCfgOpt) ([]byte, error) { var updateOpts cfgUpdateOpts @@ -236,7 +244,9 @@ func ConfigUpdate(cfgCur, cfgDef interface{}, opts ...UpdateCfgOpt) ([]byte, err outLines = append(outLines, pad+"# type: "+doc.Type) } - outLines = append(outLines, pad+"# env var: LOTUS_"+strings.ToUpper(strings.ReplaceAll(section, ".", "_"))+"_"+strings.ToUpper(lf[0])) + if !updateOpts.noEnv { + outLines = append(outLines, pad+"# env var: LOTUS_"+strings.ToUpper(strings.ReplaceAll(section, ".", "_"))+"_"+strings.ToUpper(lf[0])) + } } } From 2f36f0ec0a852a23540619706a38ec6f7c76187f Mon Sep 17 00:00:00 2001 From: "Andrew Jackson (Ajax)" Date: Fri, 22 Sep 2023 16:15:18 -0500 Subject: [PATCH 05/15] bump circleci for flaky test --- .circleci/config.yml | 4 +-- .circleci/template.yml | 4 +-- node/config/cfgdocgen/gen.go | 2 +- node/config/doc_gen.go | 70 ++++++++++++++++++------------------ 4 files changed, 40 insertions(+), 40 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index a9bb28b98..3504381d0 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,7 +1,7 @@ version: 2.1 orbs: - aws-cli: circleci/aws-cli@1.3.2 - docker: circleci/docker@2.1.4 + aws-cli: circleci/aws-cli@4.1.1 + docker: circleci/docker@2.3.0 executors: golang: diff --git a/.circleci/template.yml b/.circleci/template.yml index 89714308f..0f7a4e031 100644 --- a/.circleci/template.yml +++ b/.circleci/template.yml @@ -1,7 +1,7 @@ version: 2.1 orbs: - aws-cli: circleci/aws-cli@1.3.2 - docker: circleci/docker@2.1.4 + aws-cli: circleci/aws-cli@4.1.1 + docker: circleci/docker@2.3.0 executors: golang: diff --git a/node/config/cfgdocgen/gen.go b/node/config/cfgdocgen/gen.go index 577e85f9d..b13b7d799 100644 --- a/node/config/cfgdocgen/gen.go +++ b/node/config/cfgdocgen/gen.go @@ -104,7 +104,7 @@ var Doc = map[string][]DocField{ for _, typeName := range outt { typ := out[typeName] - fmt.Printf("\t\"%s\": []DocField{\n", typeName) + fmt.Printf("\t\"%s\": {\n", typeName) for _, f := range typ { fmt.Println("\t\t{") diff --git a/node/config/doc_gen.go b/node/config/doc_gen.go index 508d7017e..c3af2740c 100644 --- a/node/config/doc_gen.go +++ b/node/config/doc_gen.go @@ -9,7 +9,7 @@ type DocField struct { } var Doc = map[string][]DocField{ - "API": []DocField{ + "API": { { Name: "ListenAddress", Type: "string", @@ -29,7 +29,7 @@ var Doc = map[string][]DocField{ Comment: ``, }, }, - "Backup": []DocField{ + "Backup": { { Name: "DisableMetadataLog", Type: "bool", @@ -41,7 +41,7 @@ Note that in case of metadata corruption it might be much harder to recover your node if metadata log is disabled`, }, }, - "BatchFeeConfig": []DocField{ + "BatchFeeConfig": { { Name: "Base", Type: "types.FIL", @@ -55,7 +55,7 @@ your node if metadata log is disabled`, Comment: ``, }, }, - "Chainstore": []DocField{ + "Chainstore": { { Name: "EnableSplitstore", Type: "bool", @@ -69,7 +69,7 @@ your node if metadata log is disabled`, Comment: ``, }, }, - "Client": []DocField{ + "Client": { { Name: "UseIpfs", Type: "bool", @@ -117,7 +117,7 @@ without existing payment channels with available funds will fail instead of automatically performing on-chain operations.`, }, }, - "Common": []DocField{ + "Common": { { Name: "API", Type: "API", @@ -149,7 +149,7 @@ of automatically performing on-chain operations.`, Comment: ``, }, }, - "DAGStoreConfig": []DocField{ + "DAGStoreConfig": { { Name: "RootDir", Type: "string", @@ -206,7 +206,7 @@ representation, e.g. 1m, 5m, 1h. Default value: 1 minute.`, }, }, - "DealmakingConfig": []DocField{ + "DealmakingConfig": { { Name: "ConsiderOnlineStorageDeals", Type: "bool", @@ -341,7 +341,7 @@ see https://lotus.filecoin.io/storage-providers/advanced-configurations/market/# Comment: ``, }, }, - "Events": []DocField{ + "Events": { { Name: "DisableRealTimeFilterAPI", Type: "bool", @@ -394,7 +394,7 @@ the database must already exist and be writeable. If a relative path is provided relative to the CWD (current working directory).`, }, }, - "FaultReporterConfig": []DocField{ + "FaultReporterConfig": { { Name: "EnableConsensusFaultReporter", Type: "bool", @@ -423,7 +423,7 @@ ReportConsensusFault messages. It will pay for gas fees, and receive any rewards. This address should have adequate funds to cover gas fees.`, }, }, - "FeeConfig": []DocField{ + "FeeConfig": { { Name: "DefaultMaxFee", Type: "types.FIL", @@ -431,7 +431,7 @@ rewards. This address should have adequate funds to cover gas fees.`, Comment: ``, }, }, - "FevmConfig": []DocField{ + "FevmConfig": { { Name: "EnableEthRPC", Type: "bool", @@ -453,7 +453,7 @@ Set to 0 to keep all mappings`, Comment: ``, }, }, - "FullNode": []DocField{ + "FullNode": { { Name: "Client", Type: "Client", @@ -503,7 +503,7 @@ Set to 0 to keep all mappings`, Comment: ``, }, }, - "HarmonyDB": []DocField{ + "HarmonyDB": { { Name: "Hosts", Type: "[]string", @@ -536,7 +536,7 @@ in a cluster. Only 1 is required`, Comment: `The port to find Yugabyte. Blank for default.`, }, }, - "IndexConfig": []DocField{ + "IndexConfig": { { Name: "EnableMsgIndex", Type: "bool", @@ -545,7 +545,7 @@ in a cluster. Only 1 is required`, EnableMsgIndex enables indexing of messages on chain.`, }, }, - "IndexProviderConfig": []DocField{ + "IndexProviderConfig": { { Name: "Enable", Type: "bool", @@ -590,7 +590,7 @@ starts. By default, the cache is rehydrated from previously cached entries store datastore if any is present.`, }, }, - "Libp2p": []DocField{ + "Libp2p": { { Name: "ListenAddresses", Type: "[]string", @@ -657,7 +657,7 @@ count towards this limit.`, closed by the connection manager.`, }, }, - "Logging": []DocField{ + "Logging": { { Name: "SubsystemLevels", Type: "map[string]string", @@ -665,7 +665,7 @@ closed by the connection manager.`, Comment: `SubsystemLevels specify per-subsystem log levels`, }, }, - "LotusProviderAddresses": []DocField{ + "LotusProviderAddresses": { { Name: "PreCommitControl", Type: "[]string", @@ -701,7 +701,7 @@ A control address that doesn't have enough funds will still be chosen over the worker address if this flag is set.`, }, }, - "LotusProviderConfig": []DocField{ + "LotusProviderConfig": { { Name: "EnableWindowPost", Type: "bool", @@ -733,7 +733,7 @@ over the worker address if this flag is set.`, Comment: ``, }, }, - "LotusProviderFees": []DocField{ + "LotusProviderFees": { { Name: "DefaultMaxFee", Type: "types.FIL", @@ -783,7 +783,7 @@ over the worker address if this flag is set.`, Comment: ``, }, }, - "MinerAddressConfig": []DocField{ + "MinerAddressConfig": { { Name: "PreCommitControl", Type: "[]string", @@ -825,7 +825,7 @@ A control address that doesn't have enough funds will still be chosen over the worker address if this flag is set.`, }, }, - "MinerFeeConfig": []DocField{ + "MinerFeeConfig": { { Name: "MaxPreCommitGasFee", Type: "types.FIL", @@ -875,7 +875,7 @@ over the worker address if this flag is set.`, Comment: ``, }, }, - "MinerSubsystemConfig": []DocField{ + "MinerSubsystemConfig": { { Name: "EnableMining", Type: "bool", @@ -921,7 +921,7 @@ This is useful to allow workers to bypass the lotus miner to access sector infor Comment: ``, }, }, - "ProvingConfig": []DocField{ + "ProvingConfig": { { Name: "ParallelCheckLimit", Type: "int", @@ -1048,7 +1048,7 @@ Note that setting this value lower may result in less efficient gas use - more m to prove each deadline, resulting in more total gas use (but each message will have lower gas limit)`, }, }, - "Pubsub": []DocField{ + "Pubsub": { { Name: "Bootstrapper", Type: "bool", @@ -1108,7 +1108,7 @@ This property is used only if ElasticSearchTracer propery is set.`, Comment: `Auth token that will be passed with logs to elasticsearch - used for weighted peers score.`, }, }, - "RetrievalPricing": []DocField{ + "RetrievalPricing": { { Name: "Strategy", Type: "string", @@ -1128,7 +1128,7 @@ This property is used only if ElasticSearchTracer propery is set.`, Comment: ``, }, }, - "RetrievalPricingDefault": []DocField{ + "RetrievalPricingDefault": { { Name: "VerifiedDealsFreeTransfer", Type: "bool", @@ -1139,7 +1139,7 @@ This parameter is ONLY applicable if the retrieval pricing policy strategy has b default value is true`, }, }, - "RetrievalPricingExternal": []DocField{ + "RetrievalPricingExternal": { { Name: "Path", Type: "string", @@ -1148,7 +1148,7 @@ default value is true`, This parameter is ONLY applicable if the retrieval pricing policy strategy has been configured to "external".`, }, }, - "SealerConfig": []DocField{ + "SealerConfig": { { Name: "ParallelFetchLimit", Type: "int", @@ -1249,7 +1249,7 @@ to use when evaluating tasks against this worker. An empty value defaults to "hardware".`, }, }, - "SealingConfig": []DocField{ + "SealingConfig": { { Name: "MaxWaitDealsSectors", Type: "uint64", @@ -1455,7 +1455,7 @@ Submitting a smaller number of prove commits per epoch would reduce the possibil Comment: ``, }, }, - "Splitstore": []DocField{ + "Splitstore": { { Name: "ColdStoreType", Type: "string", @@ -1522,7 +1522,7 @@ is set. Moving GC will not occur when total moving size exceeds HotstoreMaxSpaceTarget - HotstoreMaxSpaceSafetyBuffer`, }, }, - "StorageMiner": []DocField{ + "StorageMiner": { { Name: "Subsystems", Type: "MinerSubsystemConfig", @@ -1584,7 +1584,7 @@ HotstoreMaxSpaceTarget - HotstoreMaxSpaceSafetyBuffer`, Comment: ``, }, }, - "UserRaftConfig": []DocField{ + "UserRaftConfig": { { Name: "ClusterModeEnabled", Type: "bool", @@ -1646,7 +1646,7 @@ copies that we keep as backups (renaming) after cleanup.`, Comment: `Tracing enables propagation of contexts across binary boundaries.`, }, }, - "Wallet": []DocField{ + "Wallet": { { Name: "RemoteBackend", Type: "string", From c99fa24ef439621316fc657245ed9adea92f7f60 Mon Sep 17 00:00:00 2001 From: "Andrew Jackson (Ajax)" Date: Fri, 22 Sep 2023 17:53:06 -0500 Subject: [PATCH 06/15] test fix, review rearrange --- node/config/def_test.go | 6 ++++++ node/config/types.go | 8 ++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/node/config/def_test.go b/node/config/def_test.go index adbb44b60..0ad0c8f2a 100644 --- a/node/config/def_test.go +++ b/node/config/def_test.go @@ -10,6 +10,8 @@ import ( "github.com/BurntSushi/toml" "github.com/stretchr/testify/require" + + "github.com/filecoin-project/lotus/node/config" ) func TestDefaultFullNodeRoundtrip(t *testing.T) { @@ -71,6 +73,10 @@ func TestDefaultMinerRoundtrip(t *testing.T) { fmt.Println(s) + // Differs between test envs + c.HarmonyDB = config.HarmonyDB{} + c2.(*StorageMiner).HarmonyDB = config.HarmonyDB{} + fmt.Println(c) fmt.Println(c2) require.True(t, reflect.DeepEqual(c, c2)) diff --git a/node/config/types.go b/node/config/types.go index 47f227b91..ac266e089 100644 --- a/node/config/types.go +++ b/node/config/types.go @@ -67,14 +67,18 @@ type StorageMiner struct { } type LotusProviderConfig struct { - EnableWindowPost bool - EnableWinningPost bool + Subsystems ProviderSubsystemsConfig Fees LotusProviderFees Addresses LotusProviderAddresses Proving ProvingConfig } +type ProviderSubsystemsConfig struct { + EnableWindowPost bool + EnableWinningPost bool +} + type DAGStoreConfig struct { // Path to the dagstore root directory. This directory contains three // subdirectories, which can be symlinked to alternative locations if From bcd0faba81cfe1e19b998d3201e8e9d17245c89f Mon Sep 17 00:00:00 2001 From: "Andrew Jackson (Ajax)" Date: Fri, 22 Sep 2023 18:23:57 -0500 Subject: [PATCH 07/15] test fix --- node/config/def_test.go | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/node/config/def_test.go b/node/config/def_test.go index 0ad0c8f2a..627b65a56 100644 --- a/node/config/def_test.go +++ b/node/config/def_test.go @@ -10,8 +10,6 @@ import ( "github.com/BurntSushi/toml" "github.com/stretchr/testify/require" - - "github.com/filecoin-project/lotus/node/config" ) func TestDefaultFullNodeRoundtrip(t *testing.T) { @@ -74,8 +72,8 @@ func TestDefaultMinerRoundtrip(t *testing.T) { fmt.Println(s) // Differs between test envs - c.HarmonyDB = config.HarmonyDB{} - c2.(*StorageMiner).HarmonyDB = config.HarmonyDB{} + c.HarmonyDB = HarmonyDB{} + c2.(*StorageMiner).HarmonyDB = HarmonyDB{} fmt.Println(c) fmt.Println(c2) From aae259c42690ba6ead19211b150ebece027617cf Mon Sep 17 00:00:00 2001 From: "Andrew Jackson (Ajax)" Date: Mon, 25 Sep 2023 14:25:02 -0500 Subject: [PATCH 08/15] gen --- .../en/default-lotus-provider-config.toml | 9 +++---- node/config/doc_gen.go | 24 ++++++++++++------- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/documentation/en/default-lotus-provider-config.toml b/documentation/en/default-lotus-provider-config.toml index 566a0859d..788aeacab 100644 --- a/documentation/en/default-lotus-provider-config.toml +++ b/documentation/en/default-lotus-provider-config.toml @@ -1,8 +1,9 @@ -# type: bool -#EnableWindowPost = false +[Subsystems] + # type: bool + #EnableWindowPost = false -# type: bool -#EnableWinningPost = false + # type: bool + #EnableWinningPost = false [Fees] diff --git a/node/config/doc_gen.go b/node/config/doc_gen.go index c3af2740c..e2e47afc7 100644 --- a/node/config/doc_gen.go +++ b/node/config/doc_gen.go @@ -703,14 +703,8 @@ over the worker address if this flag is set.`, }, "LotusProviderConfig": { { - Name: "EnableWindowPost", - Type: "bool", - - Comment: ``, - }, - { - Name: "EnableWinningPost", - Type: "bool", + Name: "Subsystems", + Type: "ProviderSubsystemsConfig", Comment: ``, }, @@ -921,6 +915,20 @@ This is useful to allow workers to bypass the lotus miner to access sector infor Comment: ``, }, }, + "ProviderSubsystemsConfig": { + { + Name: "EnableWindowPost", + Type: "bool", + + Comment: ``, + }, + { + Name: "EnableWinningPost", + Type: "bool", + + Comment: ``, + }, + }, "ProvingConfig": { { Name: "ParallelCheckLimit", From 545329311fdeff5544cbcb43f468889474f11760 Mon Sep 17 00:00:00 2001 From: "Andrew Jackson (Ajax)" Date: Tue, 26 Sep 2023 22:06:00 -0500 Subject: [PATCH 09/15] lp config after testing --- base.toml | 190 +++++++++++++++++++++++++++++ cmd/lotus-miner/init.go | 31 ++++- cmd/lotus-provider/config.go | 23 ++-- cmd/lotus-provider/main.go | 9 +- cmd/lotus-provider/run.go | 2 +- lib/harmony/harmonydb/harmonydb.go | 28 +++-- 6 files changed, 254 insertions(+), 29 deletions(-) create mode 100644 base.toml diff --git a/base.toml b/base.toml new file mode 100644 index 000000000..788aeacab --- /dev/null +++ b/base.toml @@ -0,0 +1,190 @@ +[Subsystems] + # type: bool + #EnableWindowPost = false + + # type: bool + #EnableWinningPost = false + + +[Fees] + # type: types.FIL + #DefaultMaxFee = "0.07 FIL" + + # type: types.FIL + #MaxPreCommitGasFee = "0.025 FIL" + + # type: types.FIL + #MaxCommitGasFee = "0.05 FIL" + + # type: types.FIL + #MaxTerminateGasFee = "0.5 FIL" + + # WindowPoSt is a high-value operation, so the default fee should be high. + # + # type: types.FIL + #MaxWindowPoStGasFee = "5 FIL" + + # type: types.FIL + #MaxPublishDealsFee = "0.05 FIL" + + [Fees.MaxPreCommitBatchGasFee] + # type: types.FIL + #Base = "0 FIL" + + # type: types.FIL + #PerSector = "0.02 FIL" + + [Fees.MaxCommitBatchGasFee] + # type: types.FIL + #Base = "0 FIL" + + # type: types.FIL + #PerSector = "0.03 FIL" + + +[Addresses] + # Addresses to send PreCommit messages from + # + # type: []string + #PreCommitControl = [] + + # Addresses to send Commit messages from + # + # type: []string + #CommitControl = [] + + # type: []string + #TerminateControl = [] + + # DisableOwnerFallback disables usage of the owner address for messages + # sent automatically + # + # type: bool + #DisableOwnerFallback = false + + # DisableWorkerFallback disables usage of the worker address for messages + # sent automatically, if control addresses are configured. + # A control address that doesn't have enough funds will still be chosen + # over the worker address if this flag is set. + # + # type: bool + #DisableWorkerFallback = false + + +[Proving] + # Maximum number of sector checks to run in parallel. (0 = unlimited) + # + # WARNING: Setting this value too high may make the node crash by running out of stack + # WARNING: Setting this value too low may make sector challenge reading much slower, resulting in failed PoSt due + # to late submission. + # + # After changing this option, confirm that the new value works in your setup by invoking + # 'lotus-miner proving compute window-post 0' + # + # type: int + #ParallelCheckLimit = 0 + + # Maximum amount of time a proving pre-check can take for a sector. If the check times out the sector will be skipped + # + # WARNING: Setting this value too low risks in sectors being skipped even though they are accessible, just reading the + # test challenge took longer than this timeout + # WARNING: Setting this value too high risks missing PoSt deadline in case IO operations related to this sector are + # blocked (e.g. in case of disconnected NFS mount) + # + # type: Duration + #SingleCheckTimeout = "0s" + + # Maximum amount of time a proving pre-check can take for an entire partition. If the check times out, sectors in + # the partition which didn't get checked on time will be skipped + # + # WARNING: Setting this value too low risks in sectors being skipped even though they are accessible, just reading the + # test challenge took longer than this timeout + # WARNING: Setting this value too high risks missing PoSt deadline in case IO operations related to this partition are + # blocked or slow + # + # type: Duration + #PartitionCheckTimeout = "0s" + + # Disable Window PoSt computation on the lotus-miner process even if no window PoSt workers are present. + # + # WARNING: If no windowPoSt workers are connected, window PoSt WILL FAIL resulting in faulty sectors which will need + # to be recovered. Before enabling this option, make sure your PoSt workers work correctly. + # + # After changing this option, confirm that the new value works in your setup by invoking + # 'lotus-miner proving compute window-post 0' + # + # type: bool + #DisableBuiltinWindowPoSt = false + + # Disable Winning PoSt computation on the lotus-miner process even if no winning PoSt workers are present. + # + # WARNING: If no WinningPoSt workers are connected, Winning PoSt WILL FAIL resulting in lost block rewards. + # Before enabling this option, make sure your PoSt workers work correctly. + # + # type: bool + #DisableBuiltinWinningPoSt = false + + # Disable WindowPoSt provable sector readability checks. + # + # In normal operation, when preparing to compute WindowPoSt, lotus-miner will perform a round of reading challenges + # from all sectors to confirm that those sectors can be proven. Challenges read in this process are discarded, as + # we're only interested in checking that sector data can be read. + # + # When using builtin proof computation (no PoSt workers, and DisableBuiltinWindowPoSt is set to false), this process + # can save a lot of time and compute resources in the case that some sectors are not readable - this is caused by + # the builtin logic not skipping snark computation when some sectors need to be skipped. + # + # When using PoSt workers, this process is mostly redundant, with PoSt workers challenges will be read once, and + # if challenges for some sectors aren't readable, those sectors will just get skipped. + # + # Disabling sector pre-checks will slightly reduce IO load when proving sectors, possibly resulting in shorter + # time to produce window PoSt. In setups with good IO capabilities the effect of this option on proving time should + # be negligible. + # + # NOTE: It likely is a bad idea to disable sector pre-checks in setups with no PoSt workers. + # + # NOTE: Even when this option is enabled, recovering sectors will be checked before recovery declaration message is + # sent to the chain + # + # After changing this option, confirm that the new value works in your setup by invoking + # 'lotus-miner proving compute window-post 0' + # + # type: bool + #DisableWDPoStPreChecks = false + + # Maximum number of partitions to prove in a single SubmitWindowPoSt messace. 0 = network limit (10 in nv16) + # + # A single partition may contain up to 2349 32GiB sectors, or 2300 64GiB sectors. + # + # The maximum number of sectors which can be proven in a single PoSt message is 25000 in network version 16, which + # means that a single message can prove at most 10 partitions + # + # Note that setting this value lower may result in less efficient gas use - more messages will be sent, + # to prove each deadline, resulting in more total gas use (but each message will have lower gas limit) + # + # Setting this value above the network limit has no effect + # + # type: int + #MaxPartitionsPerPoStMessage = 0 + + # In some cases when submitting DeclareFaultsRecovered messages, + # there may be too many recoveries to fit in a BlockGasLimit. + # In those cases it may be necessary to set this value to something low (eg 1); + # Note that setting this value lower may result in less efficient gas use - more messages will be sent than needed, + # resulting in more total gas use (but each message will have lower gas limit) + # + # type: int + #MaxPartitionsPerRecoveryMessage = 0 + + # Enable single partition per PoSt Message for partitions containing recovery sectors + # + # In cases when submitting PoSt messages which contain recovering sectors, the default network limit may still be + # too high to fit in the block gas limit. In those cases, it becomes useful to only house the single partition + # with recovering sectors in the post message + # + # Note that setting this value lower may result in less efficient gas use - more messages will be sent, + # to prove each deadline, resulting in more total gas use (but each message will have lower gas limit) + # + # type: bool + #SingleRecoveringPartitionPerPostMessage = false + diff --git a/cmd/lotus-miner/init.go b/cmd/lotus-miner/init.go index 80bb3fbf6..f1bac0040 100644 --- a/cmd/lotus-miner/init.go +++ b/cmd/lotus-miner/init.go @@ -16,7 +16,6 @@ import ( "github.com/google/uuid" "github.com/ipfs/go-datastore" "github.com/ipfs/go-datastore/namespace" - logging "github.com/ipfs/go-log/v2" "github.com/libp2p/go-libp2p/core/crypto" "github.com/libp2p/go-libp2p/core/peer" "github.com/mitchellh/go-homedir" @@ -122,6 +121,33 @@ var initCmd = &cli.Command{ Name: "from", Usage: "select which address to send actor creation message from", }, + &cli.StringFlag{ + Name: "db-host", + EnvVars: []string{"LOTUS_DB_HOST"}, + Usage: "Command separated list of hostnames for yugabyte cluster", + Value: "yugabyte", + }, + &cli.StringFlag{ + Name: "db-name", + EnvVars: []string{"LOTUS_DB_NAME"}, + Value: "yugabyte", + }, + &cli.StringFlag{ + Name: "db-user", + EnvVars: []string{"LOTUS_DB_USER"}, + Value: "yugabyte", + }, + &cli.StringFlag{ + Name: "db-password", + EnvVars: []string{"LOTUS_DB_PASSWORD"}, + Value: "yugabyte", + }, + &cli.StringFlag{ + Name: "db-port", + EnvVars: []string{"LOTUS_DB_PORT"}, + Hidden: true, + Value: "5433", + }, }, Subcommands: []*cli.Command{ restoreCmd, @@ -466,8 +492,7 @@ func storageMinerInit(ctx context.Context, cctx *cli.Context, api v1api.FullNode smsts := statestore.New(namespace.Wrap(mds, modules.ManagerWorkPrefix)) // TODO: run sector index init only for devnets. This is not needed for longer running networks - harmonyDB, err := harmonydb.New([]string{"127.0.0.1"}, "yugabyte", "yugabyte", "yugabyte", "5433", "", - func(s string) { logging.Logger("harmonydb").Error(s) }) + harmonyDB, err := harmonydb.New([]string{cctx.String("db-host")}, cctx.String("db-name"), cctx.String("db-user"), cctx.String("db-password"), cctx.String("db-port"), "") if err != nil { return err } diff --git a/cmd/lotus-provider/config.go b/cmd/lotus-provider/config.go index 650843aa7..a6940ddaf 100644 --- a/cmd/lotus-provider/config.go +++ b/cmd/lotus-provider/config.go @@ -2,6 +2,7 @@ package main import ( "context" + "database/sql" "errors" "fmt" "os" @@ -9,7 +10,6 @@ import ( "strings" "github.com/BurntSushi/toml" - "github.com/kr/pretty" "github.com/urfave/cli/v2" "github.com/filecoin-project/lotus/lib/harmony/harmonydb" @@ -80,7 +80,7 @@ var configSetCmd = &cli.Command{ name := strings.Split(fn, ".")[0] _, err = db.Exec(context.Background(), - `INSERT INTO harmony_config (title, config) VALUES (?,?) + `INSERT INTO harmony_config (title, config) VALUES ($1, $2) ON CONFLICT (title) DO UPDATE SET config = excluded.config`, name, string(bytes)) if err != nil { return fmt.Errorf("unable to save config layer: %w", err) @@ -106,7 +106,7 @@ var configGetCmd = &cli.Command{ } var cfg string - err = db.QueryRow(context.Background(), `SELECT config FROM harmony_config WHERE title=?`, args.First()).Scan(&cfg) + err = db.QueryRow(context.Background(), `SELECT config FROM harmony_config WHERE title=$1`, args.First()).Scan(&cfg) if err != nil { return err } @@ -126,7 +126,7 @@ var configListCmd = &cli.Command{ return err } var res []string - err = db.Select(context.Background(), &res, `SELECT title FROM harmony_confg ORDER BY title`) + err = db.Select(context.Background(), &res, `SELECT title FROM harmony_config ORDER BY title`) if err != nil { return fmt.Errorf("unable to read from db: %w", err) } @@ -140,7 +140,7 @@ var configListCmd = &cli.Command{ var configViewCmd = &cli.Command{ Name: "view", - Usage: "View stacked config layers as it will be interpreted.", + Usage: "View stacked config layers as it will be interpreted by this version of lotus-provider.", ArgsUsage: "a list of layers to be interpreted as the final config", Action: func(cctx *cli.Context) error { db, err := makeDB(cctx) @@ -152,9 +152,9 @@ var configViewCmd = &cli.Command{ return err } - fmt.Println(pretty.Sprint(lp)) - - return nil + e := toml.NewEncoder(os.Stdout) + e.Indent = " " + return e.Encode(lp) }, } @@ -163,9 +163,12 @@ func getConfig(cctx *cli.Context, db *harmonydb.DB) (*config.LotusProviderConfig have := []string{} for _, layer := range regexp.MustCompile("[ |,]").Split(cctx.String("layers"), -1) { text := "" - err := db.QueryRow(cctx.Context, `SELECT config FROM harmony_config WHERE title=?`, layer).Scan(&text) + err := db.QueryRow(cctx.Context, `SELECT config FROM harmony_config WHERE title=$1`, layer).Scan(&text) if err != nil { - return nil, fmt.Errorf("could not read layer %s: %w", layer, err) + if strings.Contains(err.Error(), sql.ErrNoRows.Error()) { + return nil, fmt.Errorf("missing layer '%s' ", layer) + } + return nil, fmt.Errorf("could not read layer '%s': %w", layer, err) } meta, err := toml.Decode(text, &lp) if err != nil { diff --git a/cmd/lotus-provider/main.go b/cmd/lotus-provider/main.go index aa53251e5..bde67c68e 100644 --- a/cmd/lotus-provider/main.go +++ b/cmd/lotus-provider/main.go @@ -112,6 +112,11 @@ func main() { EnvVars: []string{"LOTUS_LAYERS"}, Value: "base", }, + &cli.StringFlag{ + Name: FlagRepoPath, + EnvVars: []string{"LOTUS_REPO_PATH"}, + Value: "~/.lotus", + }, cliutil.FlagVeryVerbose, }, Commands: append(local, lcli.CommonCommands...), @@ -121,7 +126,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(FlagProviderRepo), c.App.Name) + build.GeneratePanicReport(c.String("panic-reports"), c.String(FlagRepoPath), c.App.Name) panic(r) } return nil @@ -133,5 +138,5 @@ func main() { } const ( - FlagProviderRepo = "provider-repo" + FlagRepoPath = "repo-path" ) diff --git a/cmd/lotus-provider/run.go b/cmd/lotus-provider/run.go index 95e5cf346..2ab189265 100644 --- a/cmd/lotus-provider/run.go +++ b/cmd/lotus-provider/run.go @@ -87,7 +87,7 @@ var runCmd = &cli.Command{ // Open repo - repoPath := cctx.String(FlagProviderRepo) + repoPath := cctx.String(FlagRepoPath) fmt.Println("repopath", repoPath) r, err := repo.NewFS(repoPath) if err != nil { diff --git a/lib/harmony/harmonydb/harmonydb.go b/lib/harmony/harmonydb/harmonydb.go index 7d7ed9d48..793841931 100644 --- a/lib/harmony/harmonydb/harmonydb.go +++ b/lib/harmony/harmonydb/harmonydb.go @@ -33,7 +33,6 @@ type DB struct { cfg *pgxpool.Config schema string hostnames []string - log func(string) } var logger = logging.Logger("harmonydb") @@ -50,7 +49,6 @@ func NewFromConfig(cfg config.HarmonyDB) (*DB, error) { cfg.Database, cfg.Port, "", - func(s string) { logger.Error(s) }, ) } @@ -63,7 +61,6 @@ func NewFromConfigWithITestID(cfg config.HarmonyDB) func(id ITestID) (*DB, error cfg.Database, cfg.Port, id, - func(s string) { logger.Error(s) }, ) } } @@ -71,7 +68,7 @@ func NewFromConfigWithITestID(cfg config.HarmonyDB) func(id ITestID) (*DB, error // New is to be called once per binary to establish the pool. // log() is for errors. It returns an upgraded database's connection. // This entry point serves both production and integration tests, so it's more DI. -func New(hosts []string, username, password, database, port string, itestID ITestID, log func(string)) (*DB, error) { +func New(hosts []string, username, password, database, port string, itestID ITestID) (*DB, error) { itest := string(itestID) connString := "" if len(hosts) > 0 { @@ -102,11 +99,11 @@ func New(hosts []string, username, password, database, port string, itestID ITes } cfg.ConnConfig.OnNotice = func(conn *pgconn.PgConn, n *pgconn.Notice) { - log("database notice: " + n.Message + ": " + n.Detail) + logger.Debug("database notice: " + n.Message + ": " + n.Detail) DBMeasures.Errors.M(1) } - db := DB{cfg: cfg, schema: schema, hostnames: hosts, log: log} // pgx populated in AddStatsAndConnect + db := DB{cfg: cfg, schema: schema, hostnames: hosts} // pgx populated in AddStatsAndConnect if err := db.addStatsAndConnect(); err != nil { return nil, err } @@ -175,7 +172,7 @@ func (db *DB) addStatsAndConnect() error { var err error db.pgx, err = pgxpool.NewWithConfig(context.Background(), db.cfg) if err != nil { - db.log(fmt.Sprintf("Unable to connect to database: %v\n", err)) + logger.Error(fmt.Sprintf("Unable to connect to database: %v\n", err)) return err } return nil @@ -229,7 +226,7 @@ func (db *DB) upgrade() error { applied TIMESTAMP DEFAULT current_timestamp )`) if err != nil { - db.log("Upgrade failed.") + logger.Error("Upgrade failed.") return err } @@ -240,7 +237,7 @@ func (db *DB) upgrade() error { var landedEntries []struct{ Entry string } err = db.Select(context.Background(), &landedEntries, "SELECT entry FROM base") if err != nil { - db.log("Cannot read entries: " + err.Error()) + logger.Error("Cannot read entries: " + err.Error()) return err } for _, l := range landedEntries { @@ -249,18 +246,23 @@ func (db *DB) upgrade() error { } dir, err := fs.ReadDir("sql") if err != nil { - db.log("Cannot read fs entries: " + err.Error()) + logger.Error("Cannot read fs entries: " + err.Error()) return err } sort.Slice(dir, func(i, j int) bool { return dir[i].Name() < dir[j].Name() }) + + if len(dir) == 0 { + logger.Error("No sql files found.") + } for _, e := range dir { name := e.Name() if landed[name] || !strings.HasSuffix(name, ".sql") { + logger.Debug("DB Schema " + name + " already applied.") continue } file, err := fs.ReadFile("sql/" + name) if err != nil { - db.log("weird embed file read err") + logger.Error("weird embed file read err") return err } for _, s := range strings.Split(string(file), ";") { // Implement the changes. @@ -270,7 +272,7 @@ func (db *DB) upgrade() error { _, err = db.pgx.Exec(context.Background(), s) if err != nil { msg := fmt.Sprintf("Could not upgrade! File %s, Query: %s, Returned: %s", name, s, err.Error()) - db.log(msg) + logger.Error(msg) return errors.New(msg) // makes devs lives easier by placing message at the end. } } @@ -278,7 +280,7 @@ func (db *DB) upgrade() error { // Mark Completed. _, err = db.Exec(context.Background(), "INSERT INTO base (entry) VALUES ($1)", name) if err != nil { - db.log("Cannot update base: " + err.Error()) + logger.Error("Cannot update base: " + err.Error()) return fmt.Errorf("cannot insert into base: %w", err) } } From 1202ddf18ca63041eb56f6bf5587a79917806187 Mon Sep 17 00:00:00 2001 From: "Andrew Jackson (Ajax)" Date: Wed, 27 Sep 2023 10:50:46 -0500 Subject: [PATCH 10/15] tidy --- go.mod | 3 --- go.sum | 2 -- 2 files changed, 5 deletions(-) diff --git a/go.mod b/go.mod index 0b2f0075d..4c654c16e 100644 --- a/go.mod +++ b/go.mod @@ -110,7 +110,6 @@ require ( github.com/jackc/pgx/v5 v5.4.1 github.com/kelseyhightower/envconfig v1.4.0 github.com/koalacxr/quantile v0.0.1 - github.com/kr/pretty v0.3.1 github.com/libp2p/go-buffer-pool v0.1.0 github.com/libp2p/go-libp2p v0.30.0 github.com/libp2p/go-libp2p-consensus v0.0.1 @@ -277,7 +276,6 @@ require ( github.com/klauspost/compress v1.16.7 // indirect github.com/klauspost/cpuid/v2 v2.2.5 // indirect github.com/koron/go-ssdp v0.0.4 // indirect - github.com/kr/text v0.2.0 // indirect github.com/leodido/go-urn v1.2.4 // indirect github.com/libp2p/go-cidranger v1.1.0 // indirect github.com/libp2p/go-flow-metrics v0.1.0 // indirect @@ -323,7 +321,6 @@ require ( github.com/quic-go/quic-go v0.37.6 // indirect github.com/quic-go/webtransport-go v0.5.3 // indirect github.com/rivo/uniseg v0.1.0 // indirect - github.com/rogpeppe/go-internal v1.9.0 // indirect github.com/rs/cors v1.7.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/shirou/gopsutil v2.18.12+incompatible // indirect diff --git a/go.sum b/go.sum index 1afa7d647..9beece7f2 100644 --- a/go.sum +++ b/go.sum @@ -979,7 +979,6 @@ github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfn github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= @@ -1526,7 +1525,6 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= -github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= From 86ec8bbf18c0149a6d8a5ad476881585cc70f415 Mon Sep 17 00:00:00 2001 From: "Andrew Jackson (Ajax)" Date: Wed, 27 Sep 2023 21:59:21 -0500 Subject: [PATCH 11/15] config docs --- documentation/en/cli-lotus-miner.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/documentation/en/cli-lotus-miner.md b/documentation/en/cli-lotus-miner.md index 8406b07cc..0aae5fbaf 100644 --- a/documentation/en/cli-lotus-miner.md +++ b/documentation/en/cli-lotus-miner.md @@ -66,6 +66,10 @@ OPTIONS: --no-local-storage don't use storageminer repo for sector storage (default: false) --gas-premium value set gas premium for initialization messages in AttoFIL (default: "0") --from value select which address to send actor creation message from + --db-host value Command separated list of hostnames for yugabyte cluster (default: "yugabyte") [$LOTUS_DB_HOST] + --db-name value (default: "yugabyte") [$LOTUS_DB_NAME] + --db-user value (default: "yugabyte") [$LOTUS_DB_USER] + --db-password value (default: "yugabyte") [$LOTUS_DB_PASSWORD] --help, -h show help ``` From a9d472a40e770f5a7ae3905442fc970e078b02d0 Mon Sep 17 00:00:00 2001 From: "Andrew Jackson (Ajax)" Date: Thu, 28 Sep 2023 10:47:40 -0500 Subject: [PATCH 12/15] lp cfg set existing defaults --- documentation/en/default-lotus-provider-config.toml | 6 +++--- node/config/def.go | 5 +++++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/documentation/en/default-lotus-provider-config.toml b/documentation/en/default-lotus-provider-config.toml index 788aeacab..c9c0c9e78 100644 --- a/documentation/en/default-lotus-provider-config.toml +++ b/documentation/en/default-lotus-provider-config.toml @@ -82,7 +82,7 @@ # 'lotus-miner proving compute window-post 0' # # type: int - #ParallelCheckLimit = 0 + #ParallelCheckLimit = 32 # Maximum amount of time a proving pre-check can take for a sector. If the check times out the sector will be skipped # @@ -92,7 +92,7 @@ # blocked (e.g. in case of disconnected NFS mount) # # type: Duration - #SingleCheckTimeout = "0s" + #SingleCheckTimeout = "10m0s" # Maximum amount of time a proving pre-check can take for an entire partition. If the check times out, sectors in # the partition which didn't get checked on time will be skipped @@ -103,7 +103,7 @@ # blocked or slow # # type: Duration - #PartitionCheckTimeout = "0s" + #PartitionCheckTimeout = "20m0s" # Disable Window PoSt computation on the lotus-miner process even if no window PoSt workers are present. # diff --git a/node/config/def.go b/node/config/def.go index df86bb965..9c33c3796 100644 --- a/node/config/def.go +++ b/node/config/def.go @@ -374,6 +374,11 @@ func DefaultLotusProvider() *LotusProviderConfig { CommitControl: []string{}, TerminateControl: []string{}, }, + Proving: ProvingConfig{ + ParallelCheckLimit: 32, + PartitionCheckTimeout: Duration(20 * time.Minute), + SingleCheckTimeout: Duration(10 * time.Minute), + }, /* HarmonyDB: HarmonyDB{ Hosts: []string{"127.0.0.1"}, From ea035f4a7f72d680b938f0660372ac8c0cfa7251 Mon Sep 17 00:00:00 2001 From: "Andrew Jackson (Ajax)" Date: Fri, 29 Sep 2023 11:56:10 -0500 Subject: [PATCH 13/15] lint, db timout, cfg rm --- chain/gen/genesis/miners.go | 3 +- chain/vectors/gen/main.go | 5 +- cmd/lotus-bench/main.go | 11 +- cmd/lotus-provider/config.go | 25 +++ .../simulation/stages/funding_stage.go | 3 +- lib/harmony/harmonydb/harmonydb.go | 5 +- orjanCheckThisIn.toml | 190 ++++++++++++++++++ storage/sealer/ffiwrapper/sealer_cgo.go | 6 +- storage/sealer/ffiwrapper/sealer_test.go | 25 +-- storage/sealer/piece_provider_test.go | 7 +- 10 files changed, 253 insertions(+), 27 deletions(-) create mode 100644 orjanCheckThisIn.toml diff --git a/chain/gen/genesis/miners.go b/chain/gen/genesis/miners.go index 2d9942464..0880f12aa 100644 --- a/chain/gen/genesis/miners.go +++ b/chain/gen/genesis/miners.go @@ -247,7 +247,8 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sys vm.Syscal } params := &markettypes.PublishStorageDealsParams{} - for _, preseal := range m.Sectors { + for _, presealTmp := range m.Sectors { + preseal := presealTmp preseal.Deal.VerifiedDeal = true preseal.Deal.EndEpoch = minerInfos[i].presealExp p := markettypes.ClientDealProposal{ diff --git a/chain/vectors/gen/main.go b/chain/vectors/gen/main.go index 658a41dc9..f4b7c82da 100644 --- a/chain/vectors/gen/main.go +++ b/chain/vectors/gen/main.go @@ -146,7 +146,10 @@ func MakeUnsignedMessageVectors() []vectors.UnsignedMessageVector { } params := make([]byte, 32) - crand.Read(params) + _, err = crand.Read(params) + if err != nil { + panic(err) + } msg := &types.Message{ To: to, diff --git a/cmd/lotus-bench/main.go b/cmd/lotus-bench/main.go index fc484c4e3..3b6f7ddae 100644 --- a/cmd/lotus-bench/main.go +++ b/cmd/lotus-bench/main.go @@ -3,10 +3,10 @@ package main import ( "bytes" "context" + "crypto/rand" "encoding/json" "fmt" "math/big" - "math/rand" "os" "path/filepath" "sync" @@ -546,7 +546,10 @@ var sealBenchCmd = &cli.Command{ } var challenge [32]byte - rand.Read(challenge[:]) + _, err = rand.Read(challenge[:]) + if err != nil { + return err + } beforePost := time.Now() @@ -776,9 +779,7 @@ func runSeals(sb *ffiwrapper.Sealer, sbfs *basicfs.Provider, numSectors int, par start := time.Now() log.Infof("[%d] Writing piece into sector...", i) - r := rand.New(rand.NewSource(100 + int64(i))) - - pi, err := sb.AddPiece(context.TODO(), sid, nil, abi.PaddedPieceSize(sectorSize).Unpadded(), r) + pi, err := sb.AddPiece(context.TODO(), sid, nil, abi.PaddedPieceSize(sectorSize).Unpadded(), rand.Reader) if err != nil { return nil, nil, err } diff --git a/cmd/lotus-provider/config.go b/cmd/lotus-provider/config.go index a6940ddaf..b9d8a93e6 100644 --- a/cmd/lotus-provider/config.go +++ b/cmd/lotus-provider/config.go @@ -25,6 +25,7 @@ var configCmd = &cli.Command{ configGetCmd, configListCmd, configViewCmd, + configRmCmd, }, } @@ -138,6 +139,30 @@ var configListCmd = &cli.Command{ }, } +var configRmCmd = &cli.Command{ + Name: "rm", + Usage: "Remvoe a named config layer.", + Flags: []cli.Flag{}, + Action: func(cctx *cli.Context) error { + args := cctx.Args() + if args.Len() != 1 { + return errors.New("must have exactly 1 arg for the layer name") + } + db, err := makeDB(cctx) + if err != nil { + return err + } + ct, err := db.Exec(context.Background(), `DELETE FROM harmony_config WHERE title=$1`, args.First()) + if err != nil { + return fmt.Errorf("unable to read from db: %w", err) + } + if ct == 0 { + return fmt.Errorf("no layer named %s", args.First()) + } + + return nil + }, +} var configViewCmd = &cli.Command{ Name: "view", Usage: "View stacked config layers as it will be interpreted by this version of lotus-provider.", diff --git a/cmd/lotus-sim/simulation/stages/funding_stage.go b/cmd/lotus-sim/simulation/stages/funding_stage.go index f75a9910d..4ce4afae1 100644 --- a/cmd/lotus-sim/simulation/stages/funding_stage.go +++ b/cmd/lotus-sim/simulation/stages/funding_stage.go @@ -166,7 +166,8 @@ func (fs *FundingStage) PackMessages(ctx context.Context, bb *blockbuilder.Block ) }() - for _, actor := range targets { + for _, actorTmp := range targets { + actor := actorTmp switch { case builtin.IsAccountActor(actor.Code): if _, err := bb.PushMessage(&types.Message{ diff --git a/lib/harmony/harmonydb/harmonydb.go b/lib/harmony/harmonydb/harmonydb.go index 793841931..279fa2ec8 100644 --- a/lib/harmony/harmonydb/harmonydb.go +++ b/lib/harmony/harmonydb/harmonydb.go @@ -169,8 +169,11 @@ func (db *DB) addStatsAndConnect() error { return nil } + // Timeout the first connection so we know if the DB is down. + ctx, ctxClose := context.WithDeadline(context.Background(), time.Now().Add(5*time.Second)) + defer ctxClose() var err error - db.pgx, err = pgxpool.NewWithConfig(context.Background(), db.cfg) + db.pgx, err = pgxpool.NewWithConfig(ctx, db.cfg) if err != nil { logger.Error(fmt.Sprintf("Unable to connect to database: %v\n", err)) return err diff --git a/orjanCheckThisIn.toml b/orjanCheckThisIn.toml new file mode 100644 index 000000000..c9c0c9e78 --- /dev/null +++ b/orjanCheckThisIn.toml @@ -0,0 +1,190 @@ +[Subsystems] + # type: bool + #EnableWindowPost = false + + # type: bool + #EnableWinningPost = false + + +[Fees] + # type: types.FIL + #DefaultMaxFee = "0.07 FIL" + + # type: types.FIL + #MaxPreCommitGasFee = "0.025 FIL" + + # type: types.FIL + #MaxCommitGasFee = "0.05 FIL" + + # type: types.FIL + #MaxTerminateGasFee = "0.5 FIL" + + # WindowPoSt is a high-value operation, so the default fee should be high. + # + # type: types.FIL + #MaxWindowPoStGasFee = "5 FIL" + + # type: types.FIL + #MaxPublishDealsFee = "0.05 FIL" + + [Fees.MaxPreCommitBatchGasFee] + # type: types.FIL + #Base = "0 FIL" + + # type: types.FIL + #PerSector = "0.02 FIL" + + [Fees.MaxCommitBatchGasFee] + # type: types.FIL + #Base = "0 FIL" + + # type: types.FIL + #PerSector = "0.03 FIL" + + +[Addresses] + # Addresses to send PreCommit messages from + # + # type: []string + #PreCommitControl = [] + + # Addresses to send Commit messages from + # + # type: []string + #CommitControl = [] + + # type: []string + #TerminateControl = [] + + # DisableOwnerFallback disables usage of the owner address for messages + # sent automatically + # + # type: bool + #DisableOwnerFallback = false + + # DisableWorkerFallback disables usage of the worker address for messages + # sent automatically, if control addresses are configured. + # A control address that doesn't have enough funds will still be chosen + # over the worker address if this flag is set. + # + # type: bool + #DisableWorkerFallback = false + + +[Proving] + # Maximum number of sector checks to run in parallel. (0 = unlimited) + # + # WARNING: Setting this value too high may make the node crash by running out of stack + # WARNING: Setting this value too low may make sector challenge reading much slower, resulting in failed PoSt due + # to late submission. + # + # After changing this option, confirm that the new value works in your setup by invoking + # 'lotus-miner proving compute window-post 0' + # + # type: int + #ParallelCheckLimit = 32 + + # Maximum amount of time a proving pre-check can take for a sector. If the check times out the sector will be skipped + # + # WARNING: Setting this value too low risks in sectors being skipped even though they are accessible, just reading the + # test challenge took longer than this timeout + # WARNING: Setting this value too high risks missing PoSt deadline in case IO operations related to this sector are + # blocked (e.g. in case of disconnected NFS mount) + # + # type: Duration + #SingleCheckTimeout = "10m0s" + + # Maximum amount of time a proving pre-check can take for an entire partition. If the check times out, sectors in + # the partition which didn't get checked on time will be skipped + # + # WARNING: Setting this value too low risks in sectors being skipped even though they are accessible, just reading the + # test challenge took longer than this timeout + # WARNING: Setting this value too high risks missing PoSt deadline in case IO operations related to this partition are + # blocked or slow + # + # type: Duration + #PartitionCheckTimeout = "20m0s" + + # Disable Window PoSt computation on the lotus-miner process even if no window PoSt workers are present. + # + # WARNING: If no windowPoSt workers are connected, window PoSt WILL FAIL resulting in faulty sectors which will need + # to be recovered. Before enabling this option, make sure your PoSt workers work correctly. + # + # After changing this option, confirm that the new value works in your setup by invoking + # 'lotus-miner proving compute window-post 0' + # + # type: bool + #DisableBuiltinWindowPoSt = false + + # Disable Winning PoSt computation on the lotus-miner process even if no winning PoSt workers are present. + # + # WARNING: If no WinningPoSt workers are connected, Winning PoSt WILL FAIL resulting in lost block rewards. + # Before enabling this option, make sure your PoSt workers work correctly. + # + # type: bool + #DisableBuiltinWinningPoSt = false + + # Disable WindowPoSt provable sector readability checks. + # + # In normal operation, when preparing to compute WindowPoSt, lotus-miner will perform a round of reading challenges + # from all sectors to confirm that those sectors can be proven. Challenges read in this process are discarded, as + # we're only interested in checking that sector data can be read. + # + # When using builtin proof computation (no PoSt workers, and DisableBuiltinWindowPoSt is set to false), this process + # can save a lot of time and compute resources in the case that some sectors are not readable - this is caused by + # the builtin logic not skipping snark computation when some sectors need to be skipped. + # + # When using PoSt workers, this process is mostly redundant, with PoSt workers challenges will be read once, and + # if challenges for some sectors aren't readable, those sectors will just get skipped. + # + # Disabling sector pre-checks will slightly reduce IO load when proving sectors, possibly resulting in shorter + # time to produce window PoSt. In setups with good IO capabilities the effect of this option on proving time should + # be negligible. + # + # NOTE: It likely is a bad idea to disable sector pre-checks in setups with no PoSt workers. + # + # NOTE: Even when this option is enabled, recovering sectors will be checked before recovery declaration message is + # sent to the chain + # + # After changing this option, confirm that the new value works in your setup by invoking + # 'lotus-miner proving compute window-post 0' + # + # type: bool + #DisableWDPoStPreChecks = false + + # Maximum number of partitions to prove in a single SubmitWindowPoSt messace. 0 = network limit (10 in nv16) + # + # A single partition may contain up to 2349 32GiB sectors, or 2300 64GiB sectors. + # + # The maximum number of sectors which can be proven in a single PoSt message is 25000 in network version 16, which + # means that a single message can prove at most 10 partitions + # + # Note that setting this value lower may result in less efficient gas use - more messages will be sent, + # to prove each deadline, resulting in more total gas use (but each message will have lower gas limit) + # + # Setting this value above the network limit has no effect + # + # type: int + #MaxPartitionsPerPoStMessage = 0 + + # In some cases when submitting DeclareFaultsRecovered messages, + # there may be too many recoveries to fit in a BlockGasLimit. + # In those cases it may be necessary to set this value to something low (eg 1); + # Note that setting this value lower may result in less efficient gas use - more messages will be sent than needed, + # resulting in more total gas use (but each message will have lower gas limit) + # + # type: int + #MaxPartitionsPerRecoveryMessage = 0 + + # Enable single partition per PoSt Message for partitions containing recovery sectors + # + # In cases when submitting PoSt messages which contain recovering sectors, the default network limit may still be + # too high to fit in the block gas limit. In those cases, it becomes useful to only house the single partition + # with recovering sectors in the post message + # + # Note that setting this value lower may result in less efficient gas use - more messages will be sent, + # to prove each deadline, resulting in more total gas use (but each message will have lower gas limit) + # + # type: bool + #SingleRecoveringPartitionPerPostMessage = false + diff --git a/storage/sealer/ffiwrapper/sealer_cgo.go b/storage/sealer/ffiwrapper/sealer_cgo.go index fb4a6e42e..c8087875e 100644 --- a/storage/sealer/ffiwrapper/sealer_cgo.go +++ b/storage/sealer/ffiwrapper/sealer_cgo.go @@ -147,7 +147,8 @@ func (sb *Sealer) DataCid(ctx context.Context, pieceSize abi.UnpaddedPieceSize, }) } - if len(piecePromises) > 0 && len(piecePromises) == 1 { // weird for linter + /* #nosec G601 -- length is verified */ + if len(piecePromises) == 1 { p := piecePromises[0] return p() } @@ -348,7 +349,8 @@ func (sb *Sealer) AddPiece(ctx context.Context, sector storiface.SectorRef, exis } stagedFile = nil - if len(piecePromises) > 0 && len(piecePromises) == 1 { // weird for linter + /* #nosec G601 -- length is verified */ + if len(piecePromises) == 1 { p := piecePromises[0] return p() } diff --git a/storage/sealer/ffiwrapper/sealer_test.go b/storage/sealer/ffiwrapper/sealer_test.go index 78c0ffb06..72de77872 100644 --- a/storage/sealer/ffiwrapper/sealer_test.go +++ b/storage/sealer/ffiwrapper/sealer_test.go @@ -3,10 +3,10 @@ package ffiwrapper import ( "bytes" "context" + "crypto/rand" "fmt" "io" "io/fs" - "math/rand" "os" "path/filepath" "runtime" @@ -52,8 +52,8 @@ type seal struct { func data(sn abi.SectorNumber, dlen abi.UnpaddedPieceSize) io.Reader { return io.MultiReader( - io.LimitReader(rand.New(rand.NewSource(42+int64(sn))), int64(123)), - io.LimitReader(rand.New(rand.NewSource(42+int64(sn))), int64(dlen-123)), + io.LimitReader(rand.Reader, int64(123)), + io.LimitReader(rand.Reader, int64(dlen-123)), ) } @@ -790,15 +790,13 @@ func TestAddPiece512M(t *testing.T) { } t.Cleanup(cleanup) - r := rand.New(rand.NewSource(0x7e5)) - c, err := sb.AddPiece(context.TODO(), storiface.SectorRef{ ID: abi.SectorID{ Miner: miner, Number: 0, }, ProofType: abi.RegisteredSealProof_StackedDrg512MiBV1_1, - }, nil, sz, io.LimitReader(r, int64(sz))) + }, nil, sz, io.LimitReader(rand.Reader, int64(sz))) if err != nil { t.Fatal(err) } @@ -876,15 +874,13 @@ func TestAddPiece512MPadded(t *testing.T) { } t.Cleanup(cleanup) - r := rand.New(rand.NewSource(0x7e5)) - c, err := sb.AddPiece(context.TODO(), storiface.SectorRef{ ID: abi.SectorID{ Miner: miner, Number: 0, }, ProofType: abi.RegisteredSealProof_StackedDrg512MiBV1_1, - }, nil, sz, io.LimitReader(r, int64(sz/4))) + }, nil, sz, io.LimitReader(rand.Reader, int64(sz/4))) if err != nil { t.Fatalf("add piece failed: %s", err) } @@ -971,7 +967,10 @@ func TestMulticoreSDR(t *testing.T) { func TestPoStChallengeAssumptions(t *testing.T) { var r [32]byte - rand.Read(r[:]) + _, err := rand.Read(r[:]) + if err != nil { + panic(err) + } r[31] &= 0x3f // behaves like a pure function @@ -1051,10 +1050,9 @@ func TestDCAPCloses(t *testing.T) { t.Cleanup(cleanup) t.Run("DataCid", func(t *testing.T) { - r := rand.New(rand.NewSource(0x7e5)) clr := &closeAssertReader{ - Reader: io.LimitReader(r, int64(sz)), + Reader: io.LimitReader(rand.Reader, int64(sz)), } c, err := sb.DataCid(context.TODO(), sz, clr) @@ -1067,10 +1065,9 @@ func TestDCAPCloses(t *testing.T) { }) t.Run("AddPiece", func(t *testing.T) { - r := rand.New(rand.NewSource(0x7e5)) clr := &closeAssertReader{ - Reader: io.LimitReader(r, int64(sz)), + Reader: io.LimitReader(rand.Reader, int64(sz)), } c, err := sb.AddPiece(context.TODO(), storiface.SectorRef{ diff --git a/storage/sealer/piece_provider_test.go b/storage/sealer/piece_provider_test.go index 4cbc79a93..de1e07a78 100644 --- a/storage/sealer/piece_provider_test.go +++ b/storage/sealer/piece_provider_test.go @@ -3,8 +3,8 @@ package sealer import ( "bytes" "context" + "crypto/rand" "io" - "math/rand" "net" "net/http" "os" @@ -195,7 +195,10 @@ type pieceProviderTestHarness struct { func generatePieceData(size uint64) []byte { bz := make([]byte, size) - rand.Read(bz) + _, err := rand.Read(bz) + if err != nil { + panic(err) + } return bz } From 4bcbc15a4016d0ee34a7b4216d506073d52b445c Mon Sep 17 00:00:00 2001 From: "Andrew Jackson (Ajax)" Date: Fri, 29 Sep 2023 13:05:51 -0500 Subject: [PATCH 14/15] aliases --- cmd/lotus-provider/config.go | 39 ++++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/cmd/lotus-provider/config.go b/cmd/lotus-provider/config.go index b9d8a93e6..295816e1b 100644 --- a/cmd/lotus-provider/config.go +++ b/cmd/lotus-provider/config.go @@ -6,7 +6,6 @@ import ( "errors" "fmt" "os" - "regexp" "strings" "github.com/BurntSushi/toml" @@ -30,8 +29,9 @@ var configCmd = &cli.Command{ } var configDefaultCmd = &cli.Command{ - Name: "default", - Usage: "Print default node config", + Name: "default", + Aliases: []string{"defaults"}, + Usage: "Print default node config", Flags: []cli.Flag{ &cli.BoolFlag{ Name: "no-comment", @@ -54,6 +54,7 @@ var configDefaultCmd = &cli.Command{ var configSetCmd = &cli.Command{ Name: "set", + Aliases: []string{"add"}, Usage: "Set a config layer or the base", ArgsUsage: "a layer's name", Action: func(cctx *cli.Context) error { @@ -94,6 +95,7 @@ var configSetCmd = &cli.Command{ var configGetCmd = &cli.Command{ Name: "get", + Aliases: []string{"cat", "show"}, Usage: "Get a config layer by name. You may want to pipe the output to a file, or use 'less'", ArgsUsage: "layer name", Action: func(cctx *cli.Context) error { @@ -118,9 +120,10 @@ var configGetCmd = &cli.Command{ } var configListCmd = &cli.Command{ - Name: "list", - Usage: "List config layers you can get.", - Flags: []cli.Flag{}, + Name: "list", + Aliases: []string{"ls"}, + Usage: "List config layers you can get.", + Flags: []cli.Flag{}, Action: func(cctx *cli.Context) error { db, err := makeDB(cctx) if err != nil { @@ -140,9 +143,10 @@ var configListCmd = &cli.Command{ } var configRmCmd = &cli.Command{ - Name: "rm", - Usage: "Remvoe a named config layer.", - Flags: []cli.Flag{}, + Name: "remove", + Aliases: []string{"rm", "del", "delete"}, + Usage: "Remove a named config layer.", + Flags: []cli.Flag{}, Action: func(cctx *cli.Context) error { args := cctx.Args() if args.Len() != 1 { @@ -164,9 +168,18 @@ var configRmCmd = &cli.Command{ }, } var configViewCmd = &cli.Command{ - Name: "view", - Usage: "View stacked config layers as it will be interpreted by this version of lotus-provider.", + Name: "interpret", + Aliases: []string{"view", "stacked", "stack"}, + Usage: "Interpret stacked config layers by this version of lotus-provider.", ArgsUsage: "a list of layers to be interpreted as the final config", + Flags: []cli.Flag{ + &cli.StringSliceFlag{ + Name: "layers", + Usage: "comma or space separated list of layers to be interpreted", + Value: cli.NewStringSlice("base"), + Required: true, + }, + }, Action: func(cctx *cli.Context) error { db, err := makeDB(cctx) if err != nil { @@ -186,7 +199,7 @@ var configViewCmd = &cli.Command{ func getConfig(cctx *cli.Context, db *harmonydb.DB) (*config.LotusProviderConfig, error) { lp := config.DefaultLotusProvider() have := []string{} - for _, layer := range regexp.MustCompile("[ |,]").Split(cctx.String("layers"), -1) { + for _, layer := range cctx.StringSlice("layers") { text := "" err := db.QueryRow(cctx.Context, `SELECT config FROM harmony_config WHERE title=$1`, layer).Scan(&text) if err != nil { @@ -203,6 +216,6 @@ func getConfig(cctx *cli.Context, db *harmonydb.DB) (*config.LotusProviderConfig have = append(have, strings.Join(k, " ")) } } - _ = have // TODO: verify that required fields are here. + _ = have // FUTURE: verify that required fields are here. return lp, nil } From 6376001a50eac815456fb803e36ebbb67a08afac Mon Sep 17 00:00:00 2001 From: "Andrew Jackson (Ajax)" Date: Mon, 2 Oct 2023 17:08:42 -0500 Subject: [PATCH 15/15] config PR changes --- base.toml | 190 ----------------------- cmd/lotus-provider/config.go | 39 +++-- orjanCheckThisIn.toml | 190 ----------------------- storage/sealer/ffiwrapper/sealer_test.go | 24 +-- 4 files changed, 45 insertions(+), 398 deletions(-) delete mode 100644 base.toml delete mode 100644 orjanCheckThisIn.toml diff --git a/base.toml b/base.toml deleted file mode 100644 index 788aeacab..000000000 --- a/base.toml +++ /dev/null @@ -1,190 +0,0 @@ -[Subsystems] - # type: bool - #EnableWindowPost = false - - # type: bool - #EnableWinningPost = false - - -[Fees] - # type: types.FIL - #DefaultMaxFee = "0.07 FIL" - - # type: types.FIL - #MaxPreCommitGasFee = "0.025 FIL" - - # type: types.FIL - #MaxCommitGasFee = "0.05 FIL" - - # type: types.FIL - #MaxTerminateGasFee = "0.5 FIL" - - # WindowPoSt is a high-value operation, so the default fee should be high. - # - # type: types.FIL - #MaxWindowPoStGasFee = "5 FIL" - - # type: types.FIL - #MaxPublishDealsFee = "0.05 FIL" - - [Fees.MaxPreCommitBatchGasFee] - # type: types.FIL - #Base = "0 FIL" - - # type: types.FIL - #PerSector = "0.02 FIL" - - [Fees.MaxCommitBatchGasFee] - # type: types.FIL - #Base = "0 FIL" - - # type: types.FIL - #PerSector = "0.03 FIL" - - -[Addresses] - # Addresses to send PreCommit messages from - # - # type: []string - #PreCommitControl = [] - - # Addresses to send Commit messages from - # - # type: []string - #CommitControl = [] - - # type: []string - #TerminateControl = [] - - # DisableOwnerFallback disables usage of the owner address for messages - # sent automatically - # - # type: bool - #DisableOwnerFallback = false - - # DisableWorkerFallback disables usage of the worker address for messages - # sent automatically, if control addresses are configured. - # A control address that doesn't have enough funds will still be chosen - # over the worker address if this flag is set. - # - # type: bool - #DisableWorkerFallback = false - - -[Proving] - # Maximum number of sector checks to run in parallel. (0 = unlimited) - # - # WARNING: Setting this value too high may make the node crash by running out of stack - # WARNING: Setting this value too low may make sector challenge reading much slower, resulting in failed PoSt due - # to late submission. - # - # After changing this option, confirm that the new value works in your setup by invoking - # 'lotus-miner proving compute window-post 0' - # - # type: int - #ParallelCheckLimit = 0 - - # Maximum amount of time a proving pre-check can take for a sector. If the check times out the sector will be skipped - # - # WARNING: Setting this value too low risks in sectors being skipped even though they are accessible, just reading the - # test challenge took longer than this timeout - # WARNING: Setting this value too high risks missing PoSt deadline in case IO operations related to this sector are - # blocked (e.g. in case of disconnected NFS mount) - # - # type: Duration - #SingleCheckTimeout = "0s" - - # Maximum amount of time a proving pre-check can take for an entire partition. If the check times out, sectors in - # the partition which didn't get checked on time will be skipped - # - # WARNING: Setting this value too low risks in sectors being skipped even though they are accessible, just reading the - # test challenge took longer than this timeout - # WARNING: Setting this value too high risks missing PoSt deadline in case IO operations related to this partition are - # blocked or slow - # - # type: Duration - #PartitionCheckTimeout = "0s" - - # Disable Window PoSt computation on the lotus-miner process even if no window PoSt workers are present. - # - # WARNING: If no windowPoSt workers are connected, window PoSt WILL FAIL resulting in faulty sectors which will need - # to be recovered. Before enabling this option, make sure your PoSt workers work correctly. - # - # After changing this option, confirm that the new value works in your setup by invoking - # 'lotus-miner proving compute window-post 0' - # - # type: bool - #DisableBuiltinWindowPoSt = false - - # Disable Winning PoSt computation on the lotus-miner process even if no winning PoSt workers are present. - # - # WARNING: If no WinningPoSt workers are connected, Winning PoSt WILL FAIL resulting in lost block rewards. - # Before enabling this option, make sure your PoSt workers work correctly. - # - # type: bool - #DisableBuiltinWinningPoSt = false - - # Disable WindowPoSt provable sector readability checks. - # - # In normal operation, when preparing to compute WindowPoSt, lotus-miner will perform a round of reading challenges - # from all sectors to confirm that those sectors can be proven. Challenges read in this process are discarded, as - # we're only interested in checking that sector data can be read. - # - # When using builtin proof computation (no PoSt workers, and DisableBuiltinWindowPoSt is set to false), this process - # can save a lot of time and compute resources in the case that some sectors are not readable - this is caused by - # the builtin logic not skipping snark computation when some sectors need to be skipped. - # - # When using PoSt workers, this process is mostly redundant, with PoSt workers challenges will be read once, and - # if challenges for some sectors aren't readable, those sectors will just get skipped. - # - # Disabling sector pre-checks will slightly reduce IO load when proving sectors, possibly resulting in shorter - # time to produce window PoSt. In setups with good IO capabilities the effect of this option on proving time should - # be negligible. - # - # NOTE: It likely is a bad idea to disable sector pre-checks in setups with no PoSt workers. - # - # NOTE: Even when this option is enabled, recovering sectors will be checked before recovery declaration message is - # sent to the chain - # - # After changing this option, confirm that the new value works in your setup by invoking - # 'lotus-miner proving compute window-post 0' - # - # type: bool - #DisableWDPoStPreChecks = false - - # Maximum number of partitions to prove in a single SubmitWindowPoSt messace. 0 = network limit (10 in nv16) - # - # A single partition may contain up to 2349 32GiB sectors, or 2300 64GiB sectors. - # - # The maximum number of sectors which can be proven in a single PoSt message is 25000 in network version 16, which - # means that a single message can prove at most 10 partitions - # - # Note that setting this value lower may result in less efficient gas use - more messages will be sent, - # to prove each deadline, resulting in more total gas use (but each message will have lower gas limit) - # - # Setting this value above the network limit has no effect - # - # type: int - #MaxPartitionsPerPoStMessage = 0 - - # In some cases when submitting DeclareFaultsRecovered messages, - # there may be too many recoveries to fit in a BlockGasLimit. - # In those cases it may be necessary to set this value to something low (eg 1); - # Note that setting this value lower may result in less efficient gas use - more messages will be sent than needed, - # resulting in more total gas use (but each message will have lower gas limit) - # - # type: int - #MaxPartitionsPerRecoveryMessage = 0 - - # Enable single partition per PoSt Message for partitions containing recovery sectors - # - # In cases when submitting PoSt messages which contain recovering sectors, the default network limit may still be - # too high to fit in the block gas limit. In those cases, it becomes useful to only house the single partition - # with recovering sectors in the post message - # - # Note that setting this value lower may result in less efficient gas use - more messages will be sent, - # to prove each deadline, resulting in more total gas use (but each message will have lower gas limit) - # - # type: bool - #SingleRecoveringPartitionPerPostMessage = false - diff --git a/cmd/lotus-provider/config.go b/cmd/lotus-provider/config.go index 295816e1b..9ec5cb52b 100644 --- a/cmd/lotus-provider/config.go +++ b/cmd/lotus-provider/config.go @@ -5,6 +5,7 @@ import ( "database/sql" "errors" "fmt" + "io" "os" "strings" @@ -55,22 +56,40 @@ var configDefaultCmd = &cli.Command{ var configSetCmd = &cli.Command{ Name: "set", Aliases: []string{"add"}, - Usage: "Set a config layer or the base", - ArgsUsage: "a layer's name", + Usage: "Set a config layer or the base by providing a filename or stdin.", + ArgsUsage: "a layer's file name", + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "title", + Usage: "title of the config layer (req'd for stdin)", + }, + }, Action: func(cctx *cli.Context) error { args := cctx.Args() - if args.Len() != 1 { - return errors.New("must have exactly 1 arg for the file name") - } + db, err := makeDB(cctx) if err != nil { return err } - fn := args.First() - bytes, err := os.ReadFile(fn) + name := cctx.String("title") + var stream io.Reader = os.Stdin + if args.Len() != 1 { + if cctx.String("title") == "" { + return errors.New("must have a title for stdin, or a file name") + } + } else { + stream, err = os.Open(args.First()) + if err != nil { + return fmt.Errorf("cannot open file %s: %w", args.First(), err) + } + if name == "" { + name = strings.Split(args.First(), ".")[0] + } + } + bytes, err := io.ReadAll(stream) if err != nil { - return fmt.Errorf("cannot read file %w", err) + return fmt.Errorf("cannot read stream/file %w", err) } lp := config.DefaultLotusProvider() // ensure it's toml @@ -80,7 +99,6 @@ var configSetCmd = &cli.Command{ } _ = lp - name := strings.Split(fn, ".")[0] _, err = db.Exec(context.Background(), `INSERT INTO harmony_config (title, config) VALUES ($1, $2) ON CONFLICT (title) DO UPDATE SET config = excluded.config`, name, string(bytes)) @@ -217,5 +235,8 @@ func getConfig(cctx *cli.Context, db *harmonydb.DB) (*config.LotusProviderConfig } } _ = have // FUTURE: verify that required fields are here. + // If config includes 3rd-party config, consider JSONSchema as a way that + // 3rd-parties can dynamically include config requirements and we can + // validate the config. Because of layering, we must validate @ startup. return lp, nil } diff --git a/orjanCheckThisIn.toml b/orjanCheckThisIn.toml deleted file mode 100644 index c9c0c9e78..000000000 --- a/orjanCheckThisIn.toml +++ /dev/null @@ -1,190 +0,0 @@ -[Subsystems] - # type: bool - #EnableWindowPost = false - - # type: bool - #EnableWinningPost = false - - -[Fees] - # type: types.FIL - #DefaultMaxFee = "0.07 FIL" - - # type: types.FIL - #MaxPreCommitGasFee = "0.025 FIL" - - # type: types.FIL - #MaxCommitGasFee = "0.05 FIL" - - # type: types.FIL - #MaxTerminateGasFee = "0.5 FIL" - - # WindowPoSt is a high-value operation, so the default fee should be high. - # - # type: types.FIL - #MaxWindowPoStGasFee = "5 FIL" - - # type: types.FIL - #MaxPublishDealsFee = "0.05 FIL" - - [Fees.MaxPreCommitBatchGasFee] - # type: types.FIL - #Base = "0 FIL" - - # type: types.FIL - #PerSector = "0.02 FIL" - - [Fees.MaxCommitBatchGasFee] - # type: types.FIL - #Base = "0 FIL" - - # type: types.FIL - #PerSector = "0.03 FIL" - - -[Addresses] - # Addresses to send PreCommit messages from - # - # type: []string - #PreCommitControl = [] - - # Addresses to send Commit messages from - # - # type: []string - #CommitControl = [] - - # type: []string - #TerminateControl = [] - - # DisableOwnerFallback disables usage of the owner address for messages - # sent automatically - # - # type: bool - #DisableOwnerFallback = false - - # DisableWorkerFallback disables usage of the worker address for messages - # sent automatically, if control addresses are configured. - # A control address that doesn't have enough funds will still be chosen - # over the worker address if this flag is set. - # - # type: bool - #DisableWorkerFallback = false - - -[Proving] - # Maximum number of sector checks to run in parallel. (0 = unlimited) - # - # WARNING: Setting this value too high may make the node crash by running out of stack - # WARNING: Setting this value too low may make sector challenge reading much slower, resulting in failed PoSt due - # to late submission. - # - # After changing this option, confirm that the new value works in your setup by invoking - # 'lotus-miner proving compute window-post 0' - # - # type: int - #ParallelCheckLimit = 32 - - # Maximum amount of time a proving pre-check can take for a sector. If the check times out the sector will be skipped - # - # WARNING: Setting this value too low risks in sectors being skipped even though they are accessible, just reading the - # test challenge took longer than this timeout - # WARNING: Setting this value too high risks missing PoSt deadline in case IO operations related to this sector are - # blocked (e.g. in case of disconnected NFS mount) - # - # type: Duration - #SingleCheckTimeout = "10m0s" - - # Maximum amount of time a proving pre-check can take for an entire partition. If the check times out, sectors in - # the partition which didn't get checked on time will be skipped - # - # WARNING: Setting this value too low risks in sectors being skipped even though they are accessible, just reading the - # test challenge took longer than this timeout - # WARNING: Setting this value too high risks missing PoSt deadline in case IO operations related to this partition are - # blocked or slow - # - # type: Duration - #PartitionCheckTimeout = "20m0s" - - # Disable Window PoSt computation on the lotus-miner process even if no window PoSt workers are present. - # - # WARNING: If no windowPoSt workers are connected, window PoSt WILL FAIL resulting in faulty sectors which will need - # to be recovered. Before enabling this option, make sure your PoSt workers work correctly. - # - # After changing this option, confirm that the new value works in your setup by invoking - # 'lotus-miner proving compute window-post 0' - # - # type: bool - #DisableBuiltinWindowPoSt = false - - # Disable Winning PoSt computation on the lotus-miner process even if no winning PoSt workers are present. - # - # WARNING: If no WinningPoSt workers are connected, Winning PoSt WILL FAIL resulting in lost block rewards. - # Before enabling this option, make sure your PoSt workers work correctly. - # - # type: bool - #DisableBuiltinWinningPoSt = false - - # Disable WindowPoSt provable sector readability checks. - # - # In normal operation, when preparing to compute WindowPoSt, lotus-miner will perform a round of reading challenges - # from all sectors to confirm that those sectors can be proven. Challenges read in this process are discarded, as - # we're only interested in checking that sector data can be read. - # - # When using builtin proof computation (no PoSt workers, and DisableBuiltinWindowPoSt is set to false), this process - # can save a lot of time and compute resources in the case that some sectors are not readable - this is caused by - # the builtin logic not skipping snark computation when some sectors need to be skipped. - # - # When using PoSt workers, this process is mostly redundant, with PoSt workers challenges will be read once, and - # if challenges for some sectors aren't readable, those sectors will just get skipped. - # - # Disabling sector pre-checks will slightly reduce IO load when proving sectors, possibly resulting in shorter - # time to produce window PoSt. In setups with good IO capabilities the effect of this option on proving time should - # be negligible. - # - # NOTE: It likely is a bad idea to disable sector pre-checks in setups with no PoSt workers. - # - # NOTE: Even when this option is enabled, recovering sectors will be checked before recovery declaration message is - # sent to the chain - # - # After changing this option, confirm that the new value works in your setup by invoking - # 'lotus-miner proving compute window-post 0' - # - # type: bool - #DisableWDPoStPreChecks = false - - # Maximum number of partitions to prove in a single SubmitWindowPoSt messace. 0 = network limit (10 in nv16) - # - # A single partition may contain up to 2349 32GiB sectors, or 2300 64GiB sectors. - # - # The maximum number of sectors which can be proven in a single PoSt message is 25000 in network version 16, which - # means that a single message can prove at most 10 partitions - # - # Note that setting this value lower may result in less efficient gas use - more messages will be sent, - # to prove each deadline, resulting in more total gas use (but each message will have lower gas limit) - # - # Setting this value above the network limit has no effect - # - # type: int - #MaxPartitionsPerPoStMessage = 0 - - # In some cases when submitting DeclareFaultsRecovered messages, - # there may be too many recoveries to fit in a BlockGasLimit. - # In those cases it may be necessary to set this value to something low (eg 1); - # Note that setting this value lower may result in less efficient gas use - more messages will be sent than needed, - # resulting in more total gas use (but each message will have lower gas limit) - # - # type: int - #MaxPartitionsPerRecoveryMessage = 0 - - # Enable single partition per PoSt Message for partitions containing recovery sectors - # - # In cases when submitting PoSt messages which contain recovering sectors, the default network limit may still be - # too high to fit in the block gas limit. In those cases, it becomes useful to only house the single partition - # with recovering sectors in the post message - # - # Note that setting this value lower may result in less efficient gas use - more messages will be sent, - # to prove each deadline, resulting in more total gas use (but each message will have lower gas limit) - # - # type: bool - #SingleRecoveringPartitionPerPostMessage = false - diff --git a/storage/sealer/ffiwrapper/sealer_test.go b/storage/sealer/ffiwrapper/sealer_test.go index 72de77872..73b2ad52f 100644 --- a/storage/sealer/ffiwrapper/sealer_test.go +++ b/storage/sealer/ffiwrapper/sealer_test.go @@ -3,10 +3,11 @@ package ffiwrapper import ( "bytes" "context" - "crypto/rand" + crand "crypto/rand" "fmt" "io" "io/fs" + "math/rand" "os" "path/filepath" "runtime" @@ -52,8 +53,8 @@ type seal struct { func data(sn abi.SectorNumber, dlen abi.UnpaddedPieceSize) io.Reader { return io.MultiReader( - io.LimitReader(rand.Reader, int64(123)), - io.LimitReader(rand.Reader, int64(dlen-123)), + io.LimitReader(rand.New(rand.NewSource(42+int64(sn))), int64(123)), + io.LimitReader(rand.New(rand.NewSource(42+int64(sn))), int64(dlen-123)), ) } @@ -790,13 +791,15 @@ func TestAddPiece512M(t *testing.T) { } t.Cleanup(cleanup) + r := rand.New(rand.NewSource(0x7e5)) + c, err := sb.AddPiece(context.TODO(), storiface.SectorRef{ ID: abi.SectorID{ Miner: miner, Number: 0, }, ProofType: abi.RegisteredSealProof_StackedDrg512MiBV1_1, - }, nil, sz, io.LimitReader(rand.Reader, int64(sz))) + }, nil, sz, io.LimitReader(r, int64(sz))) if err != nil { t.Fatal(err) } @@ -874,13 +877,15 @@ func TestAddPiece512MPadded(t *testing.T) { } t.Cleanup(cleanup) + r := rand.New(rand.NewSource(0x7e5)) + c, err := sb.AddPiece(context.TODO(), storiface.SectorRef{ ID: abi.SectorID{ Miner: miner, Number: 0, }, ProofType: abi.RegisteredSealProof_StackedDrg512MiBV1_1, - }, nil, sz, io.LimitReader(rand.Reader, int64(sz/4))) + }, nil, sz, io.LimitReader(r, int64(sz/4))) if err != nil { t.Fatalf("add piece failed: %s", err) } @@ -967,8 +972,7 @@ func TestMulticoreSDR(t *testing.T) { func TestPoStChallengeAssumptions(t *testing.T) { var r [32]byte - _, err := rand.Read(r[:]) - if err != nil { + if _, err := crand.Read(r[:]); err != nil { panic(err) } r[31] &= 0x3f @@ -1050,9 +1054,10 @@ func TestDCAPCloses(t *testing.T) { t.Cleanup(cleanup) t.Run("DataCid", func(t *testing.T) { + r := rand.New(rand.NewSource(0x7e5)) clr := &closeAssertReader{ - Reader: io.LimitReader(rand.Reader, int64(sz)), + Reader: io.LimitReader(r, int64(sz)), } c, err := sb.DataCid(context.TODO(), sz, clr) @@ -1065,9 +1070,10 @@ func TestDCAPCloses(t *testing.T) { }) t.Run("AddPiece", func(t *testing.T) { + r := rand.New(rand.NewSource(0x7e5)) clr := &closeAssertReader{ - Reader: io.LimitReader(rand.Reader, int64(sz)), + Reader: io.LimitReader(r, int64(sz)), } c, err := sb.AddPiece(context.TODO(), storiface.SectorRef{