diff --git a/cmd/lotus-provider/config.go b/cmd/lotus-provider/config.go index 44ba49beb..13156833c 100644 --- a/cmd/lotus-provider/config.go +++ b/cmd/lotus-provider/config.go @@ -9,7 +9,6 @@ import ( "path" "strings" - "github.com/BurntSushi/toml" "github.com/urfave/cli/v2" "golang.org/x/xerrors" @@ -103,7 +102,7 @@ var configSetCmd = &cli.Command{ } lp := config.DefaultLotusProvider() // ensure it's toml - _, err = toml.Decode(string(bytes), lp) + _, err = deps.LoadConfigWithUpgrades(string(bytes), lp) if err != nil { return fmt.Errorf("cannot decode file: %w", err) } diff --git a/cmd/lotus-provider/deps/deps.go b/cmd/lotus-provider/deps/deps.go index 7a8db855f..1e6180d71 100644 --- a/cmd/lotus-provider/deps/deps.go +++ b/cmd/lotus-provider/deps/deps.go @@ -10,6 +10,7 @@ import ( "net" "net/http" "os" + "regexp" "strings" "github.com/BurntSushi/toml" @@ -34,7 +35,7 @@ import ( "github.com/filecoin-project/lotus/node/modules/dtypes" "github.com/filecoin-project/lotus/node/repo" "github.com/filecoin-project/lotus/provider" - "github.com/filecoin-project/lotus/storage/ctladdr" + "github.com/filecoin-project/lotus/provider/multictladdr" "github.com/filecoin-project/lotus/storage/paths" "github.com/filecoin-project/lotus/storage/sealer" "github.com/filecoin-project/lotus/storage/sealer/ffiwrapper" @@ -95,8 +96,8 @@ type Deps struct { Full api.FullNode Verif storiface.Verifier LW *sealer.LocalWorker - As *ctladdr.AddressSelector - Maddrs []dtypes.MinerAddress + As *multictladdr.MultiAddressSelector + Maddrs map[dtypes.MinerAddress]bool Stor *paths.Remote Si *paths.DBIndex LocalStore *paths.Local @@ -151,7 +152,7 @@ func (deps *Deps) PopulateRemainingDeps(ctx context.Context, cctx *cli.Context, } if deps.As == nil { - deps.As, err = provider.AddressSelector(&deps.Cfg.Addresses)() + deps.As, err = provider.AddressSelector(deps.Cfg.Addresses)() if err != nil { return err } @@ -236,18 +237,28 @@ Get it with: jq .PrivateKey ~/.lotus-miner/keystore/MF2XI2BNNJ3XILLQOJUXMYLUMU`, deps.LW = sealer.NewLocalWorker(sealer.WorkerConfig{}, deps.Stor, deps.LocalStore, deps.Si, nil, wstates) } if len(deps.Maddrs) == 0 { - for _, s := range deps.Cfg.Addresses.MinerAddresses { - addr, err := address.NewFromString(s) - if err != nil { - return err + for _, s := range deps.Cfg.Addresses { + for _, s := range s.MinerAddresses { + addr, err := address.NewFromString(s) + if err != nil { + return err + } + deps.Maddrs[dtypes.MinerAddress(addr)] = true } - deps.Maddrs = append(deps.Maddrs, dtypes.MinerAddress(addr)) } } fmt.Println("last line of populate") return nil } +var oldAddresses = regexp.MustCompile("(?i)^[addresses]$") + +func LoadConfigWithUpgrades(text string, lp *config.LotusProviderConfig) (toml.MetaData, error) { + // allow migration from old config format that was limited to 1 wallet setup. + newText := oldAddresses.ReplaceAllString(text, "[[addresses]]") + meta, err := toml.Decode(newText, &lp) + return meta, err +} func GetConfig(cctx *cli.Context, db *harmonydb.DB) (*config.LotusProviderConfig, error) { lp := config.DefaultLotusProvider() have := []string{} @@ -265,9 +276,10 @@ func GetConfig(cctx *cli.Context, db *harmonydb.DB) (*config.LotusProviderConfig } return nil, fmt.Errorf("could not read layer '%s': %w", layer, err) } - meta, err := toml.Decode(text, &lp) + + meta, err := LoadConfigWithUpgrades(text, lp) if err != nil { - return nil, fmt.Errorf("could not read layer, bad toml %s: %w", layer, err) + return lp, fmt.Errorf("could not read layer, bad toml %s: %w", layer, err) } for _, k := range meta.Keys() { have = append(have, strings.Join(k, " ")) diff --git a/cmd/lotus-provider/migrate.go b/cmd/lotus-provider/migrate.go index 3869c7dfb..805c404bd 100644 --- a/cmd/lotus-provider/migrate.go +++ b/cmd/lotus-provider/migrate.go @@ -20,6 +20,7 @@ import ( "github.com/filecoin-project/go-address" cliutil "github.com/filecoin-project/lotus/cli/util" + "github.com/filecoin-project/lotus/cmd/lotus-provider/deps" "github.com/filecoin-project/lotus/lib/harmony/harmonydb" "github.com/filecoin-project/lotus/node/config" "github.com/filecoin-project/lotus/node/modules" @@ -124,7 +125,7 @@ func fromMiner(cctx *cli.Context) (err error) { return fmt.Errorf("could not read config.toml: %w", err) } var lpCfg config.LotusProviderConfig - _, err = toml.Decode(string(buf), &lpCfg) + _, err = deps.LoadConfigWithUpgrades(string(buf), &lpCfg) if err != nil { return fmt.Errorf("could not decode toml: %w", err) } @@ -148,7 +149,9 @@ func fromMiner(cctx *cli.Context) (err error) { return xerrors.Errorf("parsing miner actor address: %w", err) } - lpCfg.Addresses.MinerAddresses = []string{addr.String()} + lpCfg.Addresses = []config.LotusProviderAddresses{{ + MinerAddresses: []string{addr.String()}, + }} ks, err := lr.KeyStore() if err != nil { diff --git a/cmd/lotus-provider/proving.go b/cmd/lotus-provider/proving.go index 379bfdf85..eaef45db7 100644 --- a/cmd/lotus-provider/proving.go +++ b/cmd/lotus-provider/proving.go @@ -74,7 +74,8 @@ var wdPostTaskCmd = &cli.Command{ } ht := ts.Height() - addr, err := address.NewFromString(deps.Cfg.Addresses.MinerAddresses[0]) + // It's not important to be super-accurate as it's only for basic testing. + addr, err := address.NewFromString(deps.Cfg.Addresses[0].MinerAddresses[0]) if err != nil { return xerrors.Errorf("cannot get miner address %w", err) } @@ -188,7 +189,7 @@ It will not send any messages to the chain. Since it can compute any deadline, o di := dline.NewInfo(head.Height(), cctx.Uint64("deadline"), 0, 0, 0, 10 /*challenge window*/, 0, 0) - for _, maddr := range deps.Maddrs { + for maddr := range deps.Maddrs { out, err := wdPostTask.DoPartition(ctx, head, address.Address(maddr), di, cctx.Uint64("partition")) if err != nil { fmt.Println("Error computing WindowPoSt for miner", maddr, err) diff --git a/documentation/en/default-lotus-provider-config.toml b/documentation/en/default-lotus-provider-config.toml index 8573fbda1..1daee17d0 100644 --- a/documentation/en/default-lotus-provider-config.toml +++ b/documentation/en/default-lotus-provider-config.toml @@ -56,32 +56,15 @@ #PerSector = "0.03 FIL" -[Addresses] - # Addresses to send PreCommit messages from - # - # type: []string +[[Addresses]] #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 diff --git a/lib/harmony/harmonydb/sql/20230706.sql b/lib/harmony/harmonydb/sql/20230706-itest_scratch.sql similarity index 100% rename from lib/harmony/harmonydb/sql/20230706.sql rename to lib/harmony/harmonydb/sql/20230706-itest_scratch.sql diff --git a/lib/harmony/harmonydb/sql/20230712.sql b/lib/harmony/harmonydb/sql/20230712-sector_index.sql similarity index 100% rename from lib/harmony/harmonydb/sql/20230712.sql rename to lib/harmony/harmonydb/sql/20230712-sector_index.sql diff --git a/lib/harmony/harmonydb/sql/20230719.sql b/lib/harmony/harmonydb/sql/20230719-harmony.sql similarity index 100% rename from lib/harmony/harmonydb/sql/20230719.sql rename to lib/harmony/harmonydb/sql/20230719-harmony.sql diff --git a/lib/harmony/harmonydb/sql/20230823.sql b/lib/harmony/harmonydb/sql/20230823-wdpost.sql similarity index 100% rename from lib/harmony/harmonydb/sql/20230823.sql rename to lib/harmony/harmonydb/sql/20230823-wdpost.sql diff --git a/lib/harmony/harmonydb/sql/20230919.sql b/lib/harmony/harmonydb/sql/20230919-config.sql similarity index 100% rename from lib/harmony/harmonydb/sql/20230919.sql rename to lib/harmony/harmonydb/sql/20230919-config.sql diff --git a/lib/harmony/harmonydb/sql/20231103.sql b/lib/harmony/harmonydb/sql/20231103-chain_sends.sql similarity index 100% rename from lib/harmony/harmonydb/sql/20231103.sql rename to lib/harmony/harmonydb/sql/20231103-chain_sends.sql diff --git a/lib/harmony/harmonydb/sql/20231110.sql b/lib/harmony/harmonydb/sql/20231110-mining_tasks.sql similarity index 100% rename from lib/harmony/harmonydb/sql/20231110.sql rename to lib/harmony/harmonydb/sql/20231110-mining_tasks.sql diff --git a/lib/harmony/harmonydb/sql/20231113.sql b/lib/harmony/harmonydb/sql/20231113-harmony_taskhistory_oops.sql similarity index 100% rename from lib/harmony/harmonydb/sql/20231113.sql rename to lib/harmony/harmonydb/sql/20231113-harmony_taskhistory_oops.sql diff --git a/node/config/def.go b/node/config/def.go index 192ab4f5e..48b877b3b 100644 --- a/node/config/def.go +++ b/node/config/def.go @@ -349,11 +349,11 @@ func DefaultLotusProvider() *LotusProviderConfig { MaxWindowPoStGasFee: types.MustParseFIL("5"), MaxPublishDealsFee: types.MustParseFIL("0.05"), }, - Addresses: LotusProviderAddresses{ + Addresses: []LotusProviderAddresses{{ PreCommitControl: []string{}, CommitControl: []string{}, TerminateControl: []string{}, - }, + }}, Proving: ProvingConfig{ ParallelCheckLimit: 32, PartitionCheckTimeout: Duration(20 * time.Minute), diff --git a/node/config/doc_gen.go b/node/config/doc_gen.go index 8ea61c782..a63e40a42 100644 --- a/node/config/doc_gen.go +++ b/node/config/doc_gen.go @@ -740,9 +740,9 @@ over the worker address if this flag is set.`, }, { Name: "Addresses", - Type: "LotusProviderAddresses", + Type: "[]LotusProviderAddresses", - Comment: ``, + Comment: `Addresses of wallets per MinerAddress (one of the fields).`, }, { Name: "Proving", diff --git a/node/config/types.go b/node/config/types.go index 8661ce190..208d85939 100644 --- a/node/config/types.go +++ b/node/config/types.go @@ -68,8 +68,10 @@ type StorageMiner struct { type LotusProviderConfig struct { Subsystems ProviderSubsystemsConfig - Fees LotusProviderFees - Addresses LotusProviderAddresses + Fees LotusProviderFees + + // Addresses of wallets per MinerAddress (one of the fields). + Addresses []LotusProviderAddresses Proving ProvingConfig Journal JournalConfig Apis ApisConfig diff --git a/provider/address.go b/provider/address.go index f69ca3fac..84a10a5d7 100644 --- a/provider/address.go +++ b/provider/address.go @@ -5,47 +5,60 @@ import ( "github.com/filecoin-project/go-address" + "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/node/config" - "github.com/filecoin-project/lotus/storage/ctladdr" + "github.com/filecoin-project/lotus/provider/multictladdr" ) -func AddressSelector(addrConf *config.LotusProviderAddresses) func() (*ctladdr.AddressSelector, error) { - return func() (*ctladdr.AddressSelector, error) { - as := &ctladdr.AddressSelector{} +func AddressSelector(addrConf []config.LotusProviderAddresses) func() (*multictladdr.MultiAddressSelector, error) { + return func() (*multictladdr.MultiAddressSelector, error) { + as := &multictladdr.MultiAddressSelector{ + MinerMap: make(map[address.Address]api.AddressConfig), + } if addrConf == nil { return as, nil } - as.DisableOwnerFallback = addrConf.DisableOwnerFallback - as.DisableWorkerFallback = addrConf.DisableWorkerFallback + for _, addrConf := range addrConf { + for _, minerID := range addrConf.MinerAddresses { + tmp := api.AddressConfig{ + DisableOwnerFallback: addrConf.DisableOwnerFallback, + DisableWorkerFallback: addrConf.DisableWorkerFallback, + } - for _, s := range addrConf.PreCommitControl { - addr, err := address.NewFromString(s) - if err != nil { - return nil, xerrors.Errorf("parsing precommit control address: %w", err) + for _, s := range addrConf.PreCommitControl { + addr, err := address.NewFromString(s) + if err != nil { + return nil, xerrors.Errorf("parsing precommit control address: %w", err) + } + + tmp.PreCommitControl = append(tmp.PreCommitControl, addr) + } + + for _, s := range addrConf.CommitControl { + addr, err := address.NewFromString(s) + if err != nil { + return nil, xerrors.Errorf("parsing commit control address: %w", err) + } + + tmp.CommitControl = append(tmp.CommitControl, addr) + } + + for _, s := range addrConf.TerminateControl { + addr, err := address.NewFromString(s) + if err != nil { + return nil, xerrors.Errorf("parsing terminate control address: %w", err) + } + + tmp.TerminateControl = append(tmp.TerminateControl, addr) + } + a, err := address.NewFromString(minerID) + if err != nil { + return nil, xerrors.Errorf("parsing miner address %s: %w", minerID, err) + } + as.MinerMap[a] = tmp } - - as.PreCommitControl = append(as.PreCommitControl, addr) } - - for _, s := range addrConf.CommitControl { - addr, err := address.NewFromString(s) - if err != nil { - return nil, xerrors.Errorf("parsing commit control address: %w", err) - } - - as.CommitControl = append(as.CommitControl, addr) - } - - for _, s := range addrConf.TerminateControl { - addr, err := address.NewFromString(s) - if err != nil { - return nil, xerrors.Errorf("parsing terminate control address: %w", err) - } - - as.TerminateControl = append(as.TerminateControl, addr) - } - return as, nil } } diff --git a/provider/builder.go b/provider/builder.go index 81a1a7a0a..cff387970 100644 --- a/provider/builder.go +++ b/provider/builder.go @@ -11,7 +11,7 @@ import ( "github.com/filecoin-project/lotus/provider/chainsched" "github.com/filecoin-project/lotus/provider/lpmessage" "github.com/filecoin-project/lotus/provider/lpwindow" - "github.com/filecoin-project/lotus/storage/ctladdr" + "github.com/filecoin-project/lotus/provider/multictladdr" "github.com/filecoin-project/lotus/storage/paths" "github.com/filecoin-project/lotus/storage/sealer" "github.com/filecoin-project/lotus/storage/sealer/storiface" @@ -21,7 +21,7 @@ import ( func WindowPostScheduler(ctx context.Context, fc config.LotusProviderFees, pc config.ProvingConfig, api api.FullNode, verif storiface.Verifier, lw *sealer.LocalWorker, sender *lpmessage.Sender, - as *ctladdr.AddressSelector, addresses []dtypes.MinerAddress, db *harmonydb.DB, + as *multictladdr.MultiAddressSelector, addresses map[dtypes.MinerAddress]bool, db *harmonydb.DB, stor paths.Store, idx paths.SectorIndex, max int) (*lpwindow.WdPostTask, *lpwindow.WdPostSubmitTask, *lpwindow.WdPostRecoverDeclareTask, error) { chainSched := chainsched.New(api) diff --git a/provider/lpwindow/compute_task.go b/provider/lpwindow/compute_task.go index e9d582704..9fc4afe4f 100644 --- a/provider/lpwindow/compute_task.go +++ b/provider/lpwindow/compute_task.go @@ -70,7 +70,7 @@ type WdPostTask struct { windowPoStTF promise.Promise[harmonytask.AddTaskFunc] - actors []dtypes.MinerAddress + actors map[dtypes.MinerAddress]bool max int } @@ -86,9 +86,8 @@ func NewWdPostTask(db *harmonydb.DB, faultTracker sealer.FaultTracker, prover ProverPoSt, verifier storiface.Verifier, - pcs *chainsched.ProviderChainSched, - actors []dtypes.MinerAddress, + actors map[dtypes.MinerAddress]bool, max int, ) (*WdPostTask, error) { t := &WdPostTask{ @@ -356,7 +355,7 @@ func (t *WdPostTask) Adder(taskFunc harmonytask.AddTaskFunc) { } func (t *WdPostTask) processHeadChange(ctx context.Context, revert, apply *types.TipSet) error { - for _, act := range t.actors { + for act := range t.actors { maddr := address.Address(act) aid, err := address.IDFromAddress(maddr) diff --git a/provider/lpwindow/faults_simple.go b/provider/lpwindow/faults_simple.go index d43e8ee19..b596fb5a7 100644 --- a/provider/lpwindow/faults_simple.go +++ b/provider/lpwindow/faults_simple.go @@ -110,7 +110,7 @@ func (m *SimpleFaultTracker) CheckProvable(ctx context.Context, pp abi.Registere if !locked { log.Warnw("CheckProvable Sector FAULT: can't acquire read lock", "sector", sector) - addBad(sector.ID, fmt.Sprint("can't acquire read lock")) + addBad(sector.ID, "can't acquire read lock") return } diff --git a/provider/lpwindow/recover_task.go b/provider/lpwindow/recover_task.go index 12f8522b5..076ed51c1 100644 --- a/provider/lpwindow/recover_task.go +++ b/provider/lpwindow/recover_task.go @@ -22,7 +22,7 @@ import ( "github.com/filecoin-project/lotus/node/modules/dtypes" "github.com/filecoin-project/lotus/provider/chainsched" "github.com/filecoin-project/lotus/provider/lpmessage" - "github.com/filecoin-project/lotus/storage/ctladdr" + "github.com/filecoin-project/lotus/provider/multictladdr" "github.com/filecoin-project/lotus/storage/sealer" "github.com/filecoin-project/lotus/storage/wdpost" ) @@ -34,8 +34,8 @@ type WdPostRecoverDeclareTask struct { faultTracker sealer.FaultTracker maxDeclareRecoveriesGasFee types.FIL - as *ctladdr.AddressSelector - actors []dtypes.MinerAddress + as *multictladdr.MultiAddressSelector + actors map[dtypes.MinerAddress]bool startCheckTF promise.Promise[harmonytask.AddTaskFunc] } @@ -61,11 +61,11 @@ func NewWdPostRecoverDeclareTask(sender *lpmessage.Sender, db *harmonydb.DB, api WdPostRecoverDeclareTaskApi, faultTracker sealer.FaultTracker, - as *ctladdr.AddressSelector, + as *multictladdr.MultiAddressSelector, pcs *chainsched.ProviderChainSched, maxDeclareRecoveriesGasFee types.FIL, - actors []dtypes.MinerAddress) (*WdPostRecoverDeclareTask, error) { + actors map[dtypes.MinerAddress]bool) (*WdPostRecoverDeclareTask, error) { t := &WdPostRecoverDeclareTask{ sender: sender, db: db, @@ -235,7 +235,7 @@ func (w *WdPostRecoverDeclareTask) Adder(taskFunc harmonytask.AddTaskFunc) { func (w *WdPostRecoverDeclareTask) processHeadChange(ctx context.Context, revert, apply *types.TipSet) error { tf := w.startCheckTF.Val(ctx) - for _, act := range w.actors { + for act := range w.actors { maddr := address.Address(act) aid, err := address.IDFromAddress(maddr) diff --git a/provider/lpwindow/submit_task.go b/provider/lpwindow/submit_task.go index 72f2499f6..d6937354b 100644 --- a/provider/lpwindow/submit_task.go +++ b/provider/lpwindow/submit_task.go @@ -21,7 +21,7 @@ import ( "github.com/filecoin-project/lotus/lib/promise" "github.com/filecoin-project/lotus/provider/chainsched" "github.com/filecoin-project/lotus/provider/lpmessage" - "github.com/filecoin-project/lotus/storage/ctladdr" + "github.com/filecoin-project/lotus/provider/multictladdr" "github.com/filecoin-project/lotus/storage/wdpost" ) @@ -47,12 +47,12 @@ type WdPostSubmitTask struct { api WdPoStSubmitTaskApi maxWindowPoStGasFee types.FIL - as *ctladdr.AddressSelector + as *multictladdr.MultiAddressSelector submitPoStTF promise.Promise[harmonytask.AddTaskFunc] } -func NewWdPostSubmitTask(pcs *chainsched.ProviderChainSched, send *lpmessage.Sender, db *harmonydb.DB, api WdPoStSubmitTaskApi, maxWindowPoStGasFee types.FIL, as *ctladdr.AddressSelector) (*WdPostSubmitTask, error) { +func NewWdPostSubmitTask(pcs *chainsched.ProviderChainSched, send *lpmessage.Sender, db *harmonydb.DB, api WdPoStSubmitTaskApi, maxWindowPoStGasFee types.FIL, as *multictladdr.MultiAddressSelector) (*WdPostSubmitTask, error) { res := &WdPostSubmitTask{ sender: send, db: db, @@ -248,7 +248,7 @@ type MsgPrepAPI interface { StateLookupID(context.Context, address.Address, types.TipSetKey) (address.Address, error) } -func preparePoStMessage(w MsgPrepAPI, as *ctladdr.AddressSelector, maddr address.Address, msg *types.Message, maxFee abi.TokenAmount) (*types.Message, *api.MessageSendSpec, error) { +func preparePoStMessage(w MsgPrepAPI, as *multictladdr.MultiAddressSelector, maddr address.Address, msg *types.Message, maxFee abi.TokenAmount) (*types.Message, *api.MessageSendSpec, error) { mi, err := w.StateMinerInfo(context.Background(), maddr, types.EmptyTSK) if err != nil { return nil, nil, xerrors.Errorf("error getting miner info: %w", err) @@ -292,7 +292,7 @@ func preparePoStMessage(w MsgPrepAPI, as *ctladdr.AddressSelector, maddr address goodFunds := big.Add(minGasFeeMsg.RequiredFunds(), minGasFeeMsg.Value) minFunds := big.Min(big.Add(minGasFeeMsg.RequiredFunds(), minGasFeeMsg.Value), goodFunds) - from, _, err := as.AddressFor(context.Background(), w, mi, api.PoStAddr, goodFunds, minFunds) + from, _, err := as.AddressFor(context.Background(), w, maddr, mi, api.PoStAddr, goodFunds, minFunds) if err != nil { return nil, nil, xerrors.Errorf("error getting address: %w", err) } diff --git a/provider/lpwinning/winning_task.go b/provider/lpwinning/winning_task.go index bf4f2fe71..8b289a8de 100644 --- a/provider/lpwinning/winning_task.go +++ b/provider/lpwinning/winning_task.go @@ -42,7 +42,7 @@ type WinPostTask struct { verifier storiface.Verifier api WinPostAPI - actors []dtypes.MinerAddress + actors map[dtypes.MinerAddress]bool mineTF promise.Promise[harmonytask.AddTaskFunc] } @@ -70,7 +70,7 @@ type ProverWinningPoSt interface { GenerateWinningPoSt(ctx context.Context, ppt abi.RegisteredPoStProof, minerID abi.ActorID, sectorInfo []storiface.PostSectorChallenge, randomness abi.PoStRandomness) ([]prooftypes.PoStProof, error) } -func NewWinPostTask(max int, db *harmonydb.DB, prover ProverWinningPoSt, verifier storiface.Verifier, api WinPostAPI, actors []dtypes.MinerAddress) *WinPostTask { +func NewWinPostTask(max int, db *harmonydb.DB, prover ProverWinningPoSt, verifier storiface.Verifier, api WinPostAPI, actors map[dtypes.MinerAddress]bool) *WinPostTask { t := &WinPostTask{ max: max, db: db, @@ -572,7 +572,7 @@ func (t *WinPostTask) mineBasic(ctx context.Context) { baseEpoch := workBase.TipSet.Height() - for _, act := range t.actors { + for act := range t.actors { spID, err := address.IDFromAddress(address.Address(act)) if err != nil { log.Errorf("failed to get spID from address %s: %s", act, err) diff --git a/provider/multictladdr/multiaddresses.go b/provider/multictladdr/multiaddresses.go new file mode 100644 index 000000000..4f1947729 --- /dev/null +++ b/provider/multictladdr/multiaddresses.go @@ -0,0 +1,81 @@ +package multictladdr + +import ( + "context" + + logging "github.com/ipfs/go-log/v2" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/go-state-types/big" + + "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/lotus/storage/ctladdr" +) + +var log = logging.Logger("multictladdr") + +type MultiAddressSelector struct { + MinerMap map[address.Address]api.AddressConfig +} + +func (as *MultiAddressSelector) AddressFor(ctx context.Context, a ctladdr.NodeApi, minerID address.Address, mi api.MinerInfo, use api.AddrUse, goodFunds, minFunds abi.TokenAmount) (address.Address, abi.TokenAmount, error) { + if as == nil { + // should only happen in some tests + log.Warnw("smart address selection disabled, using worker address") + return mi.Worker, big.Zero(), nil + } + + tmp := as.MinerMap[minerID] + + var addrs []address.Address + switch use { + case api.PreCommitAddr: + addrs = append(addrs, tmp.PreCommitControl...) + case api.CommitAddr: + addrs = append(addrs, tmp.CommitControl...) + case api.TerminateSectorsAddr: + addrs = append(addrs, tmp.TerminateControl...) + case api.DealPublishAddr: + addrs = append(addrs, tmp.DealPublishControl...) + default: + defaultCtl := map[address.Address]struct{}{} + for _, a := range mi.ControlAddresses { + defaultCtl[a] = struct{}{} + } + delete(defaultCtl, mi.Owner) + delete(defaultCtl, mi.Worker) + + configCtl := append([]address.Address{}, tmp.PreCommitControl...) + configCtl = append(configCtl, tmp.CommitControl...) + configCtl = append(configCtl, tmp.TerminateControl...) + configCtl = append(configCtl, tmp.DealPublishControl...) + + for _, addr := range configCtl { + if addr.Protocol() != address.ID { + var err error + addr, err = a.StateLookupID(ctx, addr, types.EmptyTSK) + if err != nil { + log.Warnw("looking up control address", "address", addr, "error", err) + continue + } + } + + delete(defaultCtl, addr) + } + + for a := range defaultCtl { + addrs = append(addrs, a) + } + } + + if len(addrs) == 0 || !tmp.DisableWorkerFallback { + addrs = append(addrs, mi.Worker) + } + if !tmp.DisableOwnerFallback { + addrs = append(addrs, mi.Owner) + } + + return ctladdr.PickAddress(ctx, a, mi, goodFunds, minFunds, addrs) +} diff --git a/storage/ctladdr/addresses.go b/storage/ctladdr/addresses.go index ee778cb38..3ffa4f41e 100644 --- a/storage/ctladdr/addresses.go +++ b/storage/ctladdr/addresses.go @@ -82,10 +82,10 @@ func (as *AddressSelector) AddressFor(ctx context.Context, a NodeApi, mi api.Min addrs = append(addrs, mi.Owner) } - return pickAddress(ctx, a, mi, goodFunds, minFunds, addrs) + return PickAddress(ctx, a, mi, goodFunds, minFunds, addrs) } -func pickAddress(ctx context.Context, a NodeApi, mi api.MinerInfo, goodFunds, minFunds abi.TokenAmount, addrs []address.Address) (address.Address, abi.TokenAmount, error) { +func PickAddress(ctx context.Context, a NodeApi, mi api.MinerInfo, goodFunds, minFunds abi.TokenAmount, addrs []address.Address) (address.Address, abi.TokenAmount, error) { leastBad := mi.Worker bestAvail := minFunds