From 0006bc3d77e787fd76ae7354dc0d52cab1a28ba7 Mon Sep 17 00:00:00 2001 From: "Andrew Jackson (Ajax)" Date: Fri, 19 Jan 2024 18:48:29 -0600 Subject: [PATCH 1/5] feat: multiaddr lp --- api/types.go | 1 + cmd/lotus-provider/deps/deps.go | 24 ++++++---- cmd/lotus-provider/migrate.go | 4 +- cmd/lotus-provider/proving.go | 3 +- node/config/def.go | 4 +- node/config/types.go | 6 ++- node/impl/full/state.go | 1 + provider/address.go | 73 +++++++++++++++++------------ provider/builder.go | 2 +- provider/lpwindow/recover_task.go | 4 +- provider/lpwindow/submit_task.go | 6 +-- storage/ctladdr/multiaddresses.go | 76 +++++++++++++++++++++++++++++++ 12 files changed, 154 insertions(+), 50 deletions(-) create mode 100644 storage/ctladdr/multiaddresses.go diff --git a/api/types.go b/api/types.go index 7fd607750..e29b7c6f7 100644 --- a/api/types.go +++ b/api/types.go @@ -291,6 +291,7 @@ type ExportRef struct { } type MinerInfo struct { + MinerID address.Address Owner address.Address // Must be an ID-address. Worker address.Address // Must be an ID-address. NewWorker address.Address // Must be an ID-address. diff --git a/cmd/lotus-provider/deps/deps.go b/cmd/lotus-provider/deps/deps.go index 7a8db855f..34db9f461 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" @@ -95,7 +96,7 @@ type Deps struct { Full api.FullNode Verif storiface.Verifier LW *sealer.LocalWorker - As *ctladdr.AddressSelector + As *ctladdr.MultiAddressSelector Maddrs []dtypes.MinerAddress Stor *paths.Remote Si *paths.DBIndex @@ -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,22 @@ 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 = append(deps.Maddrs, dtypes.MinerAddress(addr)) } - deps.Maddrs = append(deps.Maddrs, dtypes.MinerAddress(addr)) } } fmt.Println("last line of populate") return nil } +var oldAddresses = regexp.MustCompile("(?i)^[addresses]$") + func GetConfig(cctx *cli.Context, db *harmonydb.DB) (*config.LotusProviderConfig, error) { lp := config.DefaultLotusProvider() have := []string{} @@ -265,7 +270,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) + + // allow migration from old config format that was limited to 1 wallet setup. + newText := oldAddresses.ReplaceAllString(text, "[[addresses]]") + meta, err := toml.Decode(newText, &lp) if err != nil { return nil, fmt.Errorf("could not read layer, bad toml %s: %w", layer, err) } diff --git a/cmd/lotus-provider/migrate.go b/cmd/lotus-provider/migrate.go index 3869c7dfb..315691788 100644 --- a/cmd/lotus-provider/migrate.go +++ b/cmd/lotus-provider/migrate.go @@ -148,7 +148,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..175372249 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) } 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/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/node/impl/full/state.go b/node/impl/full/state.go index 0e92c8e5b..d294307c1 100644 --- a/node/impl/full/state.go +++ b/node/impl/full/state.go @@ -169,6 +169,7 @@ func (m *StateModule) StateMinerInfo(ctx context.Context, actor address.Address, } ret := api.MinerInfo{ + MinerID: actor, Owner: info.Owner, Worker: info.Worker, ControlAddresses: info.ControlAddresses, diff --git a/provider/address.go b/provider/address.go index f69ca3fac..298fe8784 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" ) -func AddressSelector(addrConf *config.LotusProviderAddresses) func() (*ctladdr.AddressSelector, error) { - return func() (*ctladdr.AddressSelector, error) { - as := &ctladdr.AddressSelector{} +func AddressSelector(addrConf []config.LotusProviderAddresses) func() (*ctladdr.MultiAddressSelector, error) { + return func() (*ctladdr.MultiAddressSelector, error) { + as := &ctladdr.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..82781d211 100644 --- a/provider/builder.go +++ b/provider/builder.go @@ -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 *ctladdr.MultiAddressSelector, addresses []dtypes.MinerAddress, 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/recover_task.go b/provider/lpwindow/recover_task.go index 12f8522b5..bd88db4dc 100644 --- a/provider/lpwindow/recover_task.go +++ b/provider/lpwindow/recover_task.go @@ -34,7 +34,7 @@ type WdPostRecoverDeclareTask struct { faultTracker sealer.FaultTracker maxDeclareRecoveriesGasFee types.FIL - as *ctladdr.AddressSelector + as *ctladdr.MultiAddressSelector actors []dtypes.MinerAddress startCheckTF promise.Promise[harmonytask.AddTaskFunc] @@ -61,7 +61,7 @@ func NewWdPostRecoverDeclareTask(sender *lpmessage.Sender, db *harmonydb.DB, api WdPostRecoverDeclareTaskApi, faultTracker sealer.FaultTracker, - as *ctladdr.AddressSelector, + as *ctladdr.MultiAddressSelector, pcs *chainsched.ProviderChainSched, maxDeclareRecoveriesGasFee types.FIL, diff --git a/provider/lpwindow/submit_task.go b/provider/lpwindow/submit_task.go index 72f2499f6..6bb92ea42 100644 --- a/provider/lpwindow/submit_task.go +++ b/provider/lpwindow/submit_task.go @@ -47,12 +47,12 @@ type WdPostSubmitTask struct { api WdPoStSubmitTaskApi maxWindowPoStGasFee types.FIL - as *ctladdr.AddressSelector + as *ctladdr.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 *ctladdr.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 *ctladdr.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) diff --git a/storage/ctladdr/multiaddresses.go b/storage/ctladdr/multiaddresses.go new file mode 100644 index 000000000..54a3433e0 --- /dev/null +++ b/storage/ctladdr/multiaddresses.go @@ -0,0 +1,76 @@ +package ctladdr + +import ( + "context" + + "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" +) + +type MultiAddressSelector struct { + MinerMap map[address.Address]api.AddressConfig +} + +func (as *MultiAddressSelector) AddressFor(ctx context.Context, a NodeApi, 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[mi.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 pickAddress(ctx, a, mi, goodFunds, minFunds, addrs) +} From 1f3abf499519dfe3243a20b85fc946c35eedfe62 Mon Sep 17 00:00:00 2001 From: "Andrew Jackson (Ajax)" Date: Mon, 29 Jan 2024 18:22:50 -0600 Subject: [PATCH 2/5] also-sql naming --- build/openrpc/full.json.gz | Bin 34608 -> 34617 bytes build/openrpc/gateway.json.gz | Bin 11872 -> 11884 bytes documentation/en/api-v0-methods.md | 1 + documentation/en/api-v1-unstable-methods.md | 1 + .../en/default-lotus-provider-config.toml | 19 +----------------- go.mod | 7 +++++++ go.sum | 8 ++++++++ ...0230706.sql => 20230706-itest_scratch.sql} | 0 ...20230712.sql => 20230712-sector_index.sql} | 0 .../{20230719.sql => 20230719-harmony.sql} | 0 .../sql/{20230823.sql => 20230823-wdpost.sql} | 0 .../sql/{20230919.sql => 20230919-config.sql} | 0 ...{20231103.sql => 20231103-chain_sends.sql} | 0 ...20231110.sql => 20231110-mining_tasks.sql} | 0 ... => 20231113-harmony_taskhistory_oops.sql} | 0 node/config/doc_gen.go | 4 ++-- 16 files changed, 20 insertions(+), 20 deletions(-) rename lib/harmony/harmonydb/sql/{20230706.sql => 20230706-itest_scratch.sql} (100%) rename lib/harmony/harmonydb/sql/{20230712.sql => 20230712-sector_index.sql} (100%) rename lib/harmony/harmonydb/sql/{20230719.sql => 20230719-harmony.sql} (100%) rename lib/harmony/harmonydb/sql/{20230823.sql => 20230823-wdpost.sql} (100%) rename lib/harmony/harmonydb/sql/{20230919.sql => 20230919-config.sql} (100%) rename lib/harmony/harmonydb/sql/{20231103.sql => 20231103-chain_sends.sql} (100%) rename lib/harmony/harmonydb/sql/{20231110.sql => 20231110-mining_tasks.sql} (100%) rename lib/harmony/harmonydb/sql/{20231113.sql => 20231113-harmony_taskhistory_oops.sql} (100%) diff --git a/build/openrpc/full.json.gz b/build/openrpc/full.json.gz index 3c30e81a9427867a286d476b5eb52110c995bcae..a08ffb3f05df7d68dcc3304ffc5c2912d69cf863 100644 GIT binary patch delta 8033 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 delta 8075 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 Z`e5Vx_ix|-e*gdg|Ns3dZ5B@P1_0r8#q|IH diff --git a/build/openrpc/gateway.json.gz b/build/openrpc/gateway.json.gz index 82d638d7e432e35816cbd7fe44b39594f9c6a5f9..39055fc6affd76e88bfc885a3f1708e95c5656e3 100644 GIT binary patch delta 2623 zcmV-F3c&T?Tr`g87K!1UP90krww`GmW8-~vdO@S$YbOZdQpy@U@r$Sw2zZ039S&^}tG zpiq=eUS4`r%+y2C&&34(2y>?FBQxPGDe5)>4fex6W8FGR`B zf;~ts5{cM}bp2G0h`HG)6?o51isM$&_YzQEC~XxmmR4|COgW9pRE{d9$D$iW3aGQF zS(ZV_t~kRtgev~WoM(M%C}g?Pb{HoPL>5pbB_#VNVo86fqarpJ$l%u&F1_3CR+Z1R%+M(+iS-oSU%p^-8HtSYKqP zxA^(4k=OfQfXTYAjHe66A*&j2Qc#w`AFM!Ff32+?fj*}1 z-e?p*`$9}3GDt*5%>VX<8BHOD(FW;GF??!bmArravTJ+$tz<>Sf7 z6>1Y6W^ z8*3P+r46LMPdPev+0XHcss1BC~^&F4p=HO`>=nj zpkhfly@l+ZV`PUM{@lIytZRb*0xUips80UQCf-EmuGyu6jA4kiS_v%V8fjR^$Ts|N z_<($7UoFdhq~m*^QX`@hD!q&u>l2)kcnBwn}-Rq zCI)hC6fQ9wV>)**vck9TX280Gc07MdxLI!v;MxW-NHFUJ1e2Y#j#|&>S2eH;1sO-* zc}bRjDHLxLjKl9+oA|m2#v!oCcp!eiTaS-l|KNMmR6KifTkBuInMYFf396FMxj!c(M$} zyNkQU?B9{weHd9k_NMpU$<({U4?}x#2NwN+2(yb|d~IPGkB%^vqwSV?O_*cx1kOP4 znS^~Gw#?J}kPfar57)K*k7R&jFCY*vU=Vr8q;`m z5=0RCj&Ku-k_j4yzd{4%57&t^DZ+*|l8+ir(RcBj84^r@KV~$3Nm&QwJ;puRm6nOe z1Pd+tS3v*5*c|M&WLct`Ab10@4rI?GzcnP~His%iQopkO#Wr^zt;U;`aDqSvOX=1CV zJWp}AQ*2QU^%K^YaDjguMHF@9v>z$g38%>@VEyMnzNS@+SI^|AGp$WY4;w39(y4U? z>Ya2XH`DWE`*A8^Ei@#FA<7IfvRXFFOL=oh9u39$Ff-M*z_Pc-V_S)-s>Z7l16q=b zl^A)-WR$%)PDTiDY;D65sbL1!=I{Dd1Wxv#60$pV`*K{J_fg#;sCb-C(Jr>a~v%?mh# zSh>hx3W7{{TPUk&XDV*WE-juS7y7K_A1;w@LOI8&iPfpurq`>lFs?(T%p$|aRF^}2 zd+}4p@|6&DUhOJxD58X=&?!`cZXj8hH)6F2fdlPY3w3|f!tq>@V#0 zh3OgO(3P(goO*HYB8-4@xSK+@N@n7UcG(`zr#ZJSVo_SJD(I_AOZ)4nd3hG+ez2@&VN!>5Sg#9 z07k0BTn2wZ<&PI~*ry7DLv6A0*D-GpZ5}fZ$;jIbC8_j|n3~v4sVN#OIuR}6H?Lb~ z?p77$PKuZ#=;H9vT3)G@oU4JTpBUN%LnOhUettE@d?Q!ar zh(v#hL(8)ndmN-er`I{?w_E0s<5_nn&;d#n5;=e(^v(|^c<*KmyoC5)2;uFQ)JFUQ z9H;y){uShx>MZD(dTYF)eu^VBK6fjNd8EKs5GW5%ibS*XZ(2RL#<`!0I19h~B`&G> zrS_j>>GGhYs^b?p?9tO9MbVf8P%I=VzpFQ-!YrU-O8jPiGo@&+V17*yluQ6*cRPM8 hfWj%M_`=GNb`E>y&xQf(TAJv$KcdEyIuGf zpYDJEKRhy9=EdB>C`9biQfFU~YkLn@-VMI;J#TbN_WU50C`5lJ==FQMhx@&Q-rhl~ z1Mo5VdbDjoi@qFtZUEh29((|E2cJ4%Mv5253nEFVWFK<{VOr)9bm0hDh<=Bn$G6ZY zqUX=KhXGSsKL^m}f9JF7;(-ewUBZWwVK3nW5B3s1URB|ur4v?k9uQ^5r<<)kK4?Wvfoif#cZAhM!nSvr?pafbYbs`SSU zWPPMA7Es0PCHp7RMW~}9HW!G}*B0Wu+wOl>mDHklmUs^ZzE5GRgmhoC z6l4NO%rGHMYjkPz>(J(iHb=JUy)Gxg^gF=-IppPN>YY%jsJZV$ z7iax%KJx5z*6O)y!v*zq{V{`yBk0)i0+{@o0LOvuIC(;x5yx}vjYjdaFT^w=gG6M+ z+-P5z(G*e`ZIJF1!>1-z$;(fkcQ*vqU3wBH&~kqOwPREBkxj!*mMG*}q5C7$H1#b+ zdZad2xI@84i1cL`Akvg#h|r-bk7`0Da>5*QF+Nw^e@OcI3p(zy0sRn@3Vh#x%vj$C-J!mzpi1-$yL z@y4c<$+cU_iMh5FOgIl%o)xEOzisYYM4S0l+`entI!6HHgLA+Tul%^?_5p26ESbn zH^J3=eO(k~FCA33-D}}iBm?lbk-pf2x5KI`AlGo_fTbd{54#E~mW0z=$lf_dcF2F> z&)s{^x+eH9z~aM!>g4Zi;!R}knq4Z$7=~D@mB2!-k%o1QY{L(S56EW*MgX1BJKAQ5 z+%d&=7e~4bv<(zP+cC~@s7sDKe+q45xHNzf8&JRqnV4m~d6*z;Vj$N>;S$3!rgH}) zD}4KI2CO@1$D@Rs_0|BcZ2*G=vrcG0Fxg4#sP%k)RRghGyz zN6A~(kW5HcWMd-6AQVi(IEP|-QHr^UjF+&RqKMv**-7WyQrl0L^-PXB)7q5uu(9HQC7oJV zpx#MGax*MD33oLtUJhqjXs%pF{F`y-> zSc#FROh(zu-eiOT$JRD1FH}wVr-+Tl7>$}BQ$Om#Wb zHx55_EMEyh=hd$Ah9XK>3Y|hF=mwI7c_UU*5IE4TwYWAd_RiI1Cy7t#0(}KF`@(Kt zn4UonUHR(1sTb!i!U#BjR}QqtFextxEe!1wu)Ky3z_&Bcqk_YH9}?(gL7Q&TdoC?J zdXt4lTmBB0wQkrA3P0DM@73$K@H;GY_hj^mxbsN?1|o1!m^tp_znye_?))cJ1(Ess z3Sgv4%w-T%{&*pWeX1Zh)D|mQ9rFg!<}ve-jJ(ZIl1lH0sfpcxZknR8q7%^~e)GC@ z=5AFX?WFKHf-Vjp&DCxqEdsP=f(X&07|jb+vn!fIeadpl3Y!>T{JivKt#C>xoLQpC zYnlZu1ipUzHQgV$+v!ym@?@0mug?zsCuM~GhFGAlnV)8Un)y9j=GU*P()a}+tQrEq z`j)Y~qB>a=w7Za?v)hQR4iOoUaab^@#g*2xj-$d)%B+mI8r62lDRdZ+*-1T+#aW1 ziAa<ZdqD<8!yNm`4hH1%dMLq)0S7|EAT0Yn=P3h_mp!U*eLA zUuyqJmM#xUsycpw!yY{yQWT9j0L4O*^1DhZ%mON=#Bb&|Q;PNq=GO#4$pk=lx8uhG iD4ddtFRTm~Y3HzKK0bbb{C@!e0RR7cYS-^;jRF7%3JfFw diff --git a/documentation/en/api-v0-methods.md b/documentation/en/api-v0-methods.md index 9110c1c3b..04e26493c 100644 --- a/documentation/en/api-v0-methods.md +++ b/documentation/en/api-v0-methods.md @@ -5995,6 +5995,7 @@ Inputs: Response: ```json { + "MinerID": "f01234", "Owner": "f01234", "Worker": "f01234", "NewWorker": "f01234", diff --git a/documentation/en/api-v1-unstable-methods.md b/documentation/en/api-v1-unstable-methods.md index 53b5ddbe6..e3107fc6c 100644 --- a/documentation/en/api-v1-unstable-methods.md +++ b/documentation/en/api-v1-unstable-methods.md @@ -7621,6 +7621,7 @@ Inputs: Response: ```json { + "MinerID": "f01234", "Owner": "f01234", "Worker": "f01234", "NewWorker": "f01234", 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/go.mod b/go.mod index c1b353fab..1acbfa7e8 100644 --- a/go.mod +++ b/go.mod @@ -166,6 +166,12 @@ require ( gotest.tools v2.2.0+incompatible ) +require ( + github.com/bahlo/generic-list-go v0.2.0 // indirect + github.com/buger/jsonparser v1.1.1 // indirect + github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect +) + require ( github.com/GeertJohan/go.incremental v1.0.0 // indirect github.com/PuerkitoBio/purell v1.1.1 // indirect @@ -225,6 +231,7 @@ require ( github.com/hashicorp/golang-lru v0.6.0 // indirect github.com/huin/goupnp v1.2.0 // indirect github.com/iancoleman/orderedmap v0.1.0 // indirect + github.com/invopop/jsonschema v0.12.0 github.com/ipfs/go-bitfield v1.1.0 // indirect github.com/ipfs/go-blockservice v0.5.1 // indirect github.com/ipfs/go-ipfs-blockstore v1.3.0 // indirect diff --git a/go.sum b/go.sum index a7983d80c..8cc338de2 100644 --- a/go.sum +++ b/go.sum @@ -102,6 +102,8 @@ github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6l github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= +github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk= +github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o= @@ -135,6 +137,8 @@ github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46f github.com/buger/goterm v1.0.3 h1:7V/HeAQHrzPk/U4BvyH2g9u+xbUW9nr4yRPyG59W4fM= github.com/buger/goterm v1.0.3/go.mod h1:HiFWV3xnkolgrBV3mY8m0X0Pumt4zg4QhbdOzQtB8tE= github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= +github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs= +github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -630,6 +634,8 @@ github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANyt github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= github.com/influxdata/influxdb1-client v0.0.0-20200827194710-b269163b24ab h1:HqW4xhhynfjrtEiiSGcQUd6vrK23iMam1FO8rI7mwig= github.com/influxdata/influxdb1-client v0.0.0-20200827194710-b269163b24ab/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= +github.com/invopop/jsonschema v0.12.0 h1:6ovsNSuvn9wEQVOyc72aycBMVQFKz7cPdMJn10CvzRI= +github.com/invopop/jsonschema v0.12.0/go.mod h1:ffZ5Km5SWWRAIN6wbDXItl95euhFz2uON45H2qjYt+0= github.com/ipfs/bbloom v0.0.1/go.mod h1:oqo8CVWsJFMOZqTglBG4wydCE4IQA/G2/SEofB0rjUI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= @@ -1635,6 +1641,8 @@ github.com/whyrusleeping/mdns v0.0.0-20180901202407-ef14215e6b30/go.mod h1:j4l84 github.com/whyrusleeping/mdns v0.0.0-20190826153040-b9b60ed33aa9/go.mod h1:j4l84WPFclQPj320J9gp0XwNKBb3U0zt5CBqjPp22G4= github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 h1:E9S12nwJwEOXe2d6gT6qxdvqMnNq+VnSsKPgm2ZZNds= github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7/go.mod h1:X2c0RVCI1eSUFI8eLcY3c0423ykwiUdxLJtkDvruhjI= +github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc= +github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+xBAnxjb1X5vnTw= github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= 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/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", From a0867a2a60f7f39fcf58825a77c1f6729ccf35c6 Mon Sep 17 00:00:00 2001 From: "Andrew Jackson (Ajax)" Date: Tue, 30 Jan 2024 16:44:08 -0600 Subject: [PATCH 3/5] fix: lp multiaddr, minerID rm, cfg upgrade --- api/types.go | 1 - cmd/lotus-provider/config.go | 3 +-- cmd/lotus-provider/deps/deps.go | 12 ++++++++---- cmd/lotus-provider/migrate.go | 3 ++- node/impl/full/state.go | 1 - provider/lpwindow/submit_task.go | 2 +- storage/ctladdr/multiaddresses.go | 4 ++-- 7 files changed, 14 insertions(+), 12 deletions(-) diff --git a/api/types.go b/api/types.go index e29b7c6f7..7fd607750 100644 --- a/api/types.go +++ b/api/types.go @@ -291,7 +291,6 @@ type ExportRef struct { } type MinerInfo struct { - MinerID address.Address Owner address.Address // Must be an ID-address. Worker address.Address // Must be an ID-address. NewWorker address.Address // Must be an ID-address. 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 34db9f461..d5ccd30c3 100644 --- a/cmd/lotus-provider/deps/deps.go +++ b/cmd/lotus-provider/deps/deps.go @@ -253,6 +253,12 @@ Get it with: jq .PrivateKey ~/.lotus-miner/keystore/MF2XI2BNNJ3XILLQOJUXMYLUMU`, 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{} @@ -271,11 +277,9 @@ func GetConfig(cctx *cli.Context, db *harmonydb.DB) (*config.LotusProviderConfig return nil, fmt.Errorf("could not read layer '%s': %w", layer, err) } - // allow migration from old config format that was limited to 1 wallet setup. - newText := oldAddresses.ReplaceAllString(text, "[[addresses]]") - meta, err := toml.Decode(newText, &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 315691788..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) } diff --git a/node/impl/full/state.go b/node/impl/full/state.go index d294307c1..0e92c8e5b 100644 --- a/node/impl/full/state.go +++ b/node/impl/full/state.go @@ -169,7 +169,6 @@ func (m *StateModule) StateMinerInfo(ctx context.Context, actor address.Address, } ret := api.MinerInfo{ - MinerID: actor, Owner: info.Owner, Worker: info.Worker, ControlAddresses: info.ControlAddresses, diff --git a/provider/lpwindow/submit_task.go b/provider/lpwindow/submit_task.go index 6bb92ea42..6283c7f74 100644 --- a/provider/lpwindow/submit_task.go +++ b/provider/lpwindow/submit_task.go @@ -292,7 +292,7 @@ func preparePoStMessage(w MsgPrepAPI, as *ctladdr.MultiAddressSelector, maddr ad 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/storage/ctladdr/multiaddresses.go b/storage/ctladdr/multiaddresses.go index 54a3433e0..fbb153e84 100644 --- a/storage/ctladdr/multiaddresses.go +++ b/storage/ctladdr/multiaddresses.go @@ -15,14 +15,14 @@ type MultiAddressSelector struct { MinerMap map[address.Address]api.AddressConfig } -func (as *MultiAddressSelector) AddressFor(ctx context.Context, a NodeApi, mi api.MinerInfo, use api.AddrUse, goodFunds, minFunds abi.TokenAmount) (address.Address, abi.TokenAmount, error) { +func (as *MultiAddressSelector) AddressFor(ctx context.Context, a 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[mi.MinerID] + tmp := as.MinerMap[minerID] var addrs []address.Address switch use { From 425e672ef6deaefa05b5906c82dab892df758577 Mon Sep 17 00:00:00 2001 From: "Andrew Jackson (Ajax)" Date: Mon, 12 Feb 2024 19:03:45 -0600 Subject: [PATCH 4/5] lp:feat multiaddr, comments --- cmd/lotus-provider/deps/deps.go | 8 ++++---- cmd/lotus-provider/proving.go | 2 +- go.mod | 7 ------- go.sum | 8 -------- provider/address.go | 8 ++++---- provider/builder.go | 4 ++-- provider/lpwindow/compute_task.go | 7 +++---- provider/lpwindow/faults_simple.go | 2 +- provider/lpwindow/recover_task.go | 12 ++++++------ provider/lpwindow/submit_task.go | 8 ++++---- provider/lpwinning/winning_task.go | 6 +++--- .../multictladdr}/multiaddresses.go | 11 ++++++++--- storage/ctladdr/addresses.go | 4 ++-- 13 files changed, 38 insertions(+), 49 deletions(-) rename {storage/ctladdr => provider/multictladdr}/multiaddresses.go (83%) diff --git a/cmd/lotus-provider/deps/deps.go b/cmd/lotus-provider/deps/deps.go index d5ccd30c3..1e6180d71 100644 --- a/cmd/lotus-provider/deps/deps.go +++ b/cmd/lotus-provider/deps/deps.go @@ -35,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" @@ -96,8 +96,8 @@ type Deps struct { Full api.FullNode Verif storiface.Verifier LW *sealer.LocalWorker - As *ctladdr.MultiAddressSelector - Maddrs []dtypes.MinerAddress + As *multictladdr.MultiAddressSelector + Maddrs map[dtypes.MinerAddress]bool Stor *paths.Remote Si *paths.DBIndex LocalStore *paths.Local @@ -243,7 +243,7 @@ Get it with: jq .PrivateKey ~/.lotus-miner/keystore/MF2XI2BNNJ3XILLQOJUXMYLUMU`, if err != nil { return err } - deps.Maddrs = append(deps.Maddrs, dtypes.MinerAddress(addr)) + deps.Maddrs[dtypes.MinerAddress(addr)] = true } } } diff --git a/cmd/lotus-provider/proving.go b/cmd/lotus-provider/proving.go index 175372249..eaef45db7 100644 --- a/cmd/lotus-provider/proving.go +++ b/cmd/lotus-provider/proving.go @@ -189,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/go.mod b/go.mod index 1acbfa7e8..c1b353fab 100644 --- a/go.mod +++ b/go.mod @@ -166,12 +166,6 @@ require ( gotest.tools v2.2.0+incompatible ) -require ( - github.com/bahlo/generic-list-go v0.2.0 // indirect - github.com/buger/jsonparser v1.1.1 // indirect - github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect -) - require ( github.com/GeertJohan/go.incremental v1.0.0 // indirect github.com/PuerkitoBio/purell v1.1.1 // indirect @@ -231,7 +225,6 @@ require ( github.com/hashicorp/golang-lru v0.6.0 // indirect github.com/huin/goupnp v1.2.0 // indirect github.com/iancoleman/orderedmap v0.1.0 // indirect - github.com/invopop/jsonschema v0.12.0 github.com/ipfs/go-bitfield v1.1.0 // indirect github.com/ipfs/go-blockservice v0.5.1 // indirect github.com/ipfs/go-ipfs-blockstore v1.3.0 // indirect diff --git a/go.sum b/go.sum index 8cc338de2..a7983d80c 100644 --- a/go.sum +++ b/go.sum @@ -102,8 +102,6 @@ github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6l github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= -github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk= -github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o= @@ -137,8 +135,6 @@ github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46f github.com/buger/goterm v1.0.3 h1:7V/HeAQHrzPk/U4BvyH2g9u+xbUW9nr4yRPyG59W4fM= github.com/buger/goterm v1.0.3/go.mod h1:HiFWV3xnkolgrBV3mY8m0X0Pumt4zg4QhbdOzQtB8tE= github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= -github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs= -github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -634,8 +630,6 @@ github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANyt github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= github.com/influxdata/influxdb1-client v0.0.0-20200827194710-b269163b24ab h1:HqW4xhhynfjrtEiiSGcQUd6vrK23iMam1FO8rI7mwig= github.com/influxdata/influxdb1-client v0.0.0-20200827194710-b269163b24ab/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= -github.com/invopop/jsonschema v0.12.0 h1:6ovsNSuvn9wEQVOyc72aycBMVQFKz7cPdMJn10CvzRI= -github.com/invopop/jsonschema v0.12.0/go.mod h1:ffZ5Km5SWWRAIN6wbDXItl95euhFz2uON45H2qjYt+0= github.com/ipfs/bbloom v0.0.1/go.mod h1:oqo8CVWsJFMOZqTglBG4wydCE4IQA/G2/SEofB0rjUI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= @@ -1641,8 +1635,6 @@ github.com/whyrusleeping/mdns v0.0.0-20180901202407-ef14215e6b30/go.mod h1:j4l84 github.com/whyrusleeping/mdns v0.0.0-20190826153040-b9b60ed33aa9/go.mod h1:j4l84WPFclQPj320J9gp0XwNKBb3U0zt5CBqjPp22G4= github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 h1:E9S12nwJwEOXe2d6gT6qxdvqMnNq+VnSsKPgm2ZZNds= github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7/go.mod h1:X2c0RVCI1eSUFI8eLcY3c0423ykwiUdxLJtkDvruhjI= -github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc= -github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+xBAnxjb1X5vnTw= github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= diff --git a/provider/address.go b/provider/address.go index 298fe8784..84a10a5d7 100644 --- a/provider/address.go +++ b/provider/address.go @@ -7,12 +7,12 @@ import ( "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.MultiAddressSelector, error) { - return func() (*ctladdr.MultiAddressSelector, error) { - as := &ctladdr.MultiAddressSelector{ +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 { diff --git a/provider/builder.go b/provider/builder.go index 82781d211..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.MultiAddressSelector, 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 bd88db4dc..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.MultiAddressSelector - 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.MultiAddressSelector, + 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 6283c7f74..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.MultiAddressSelector + 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.MultiAddressSelector) (*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.MultiAddressSelector, 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) 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/storage/ctladdr/multiaddresses.go b/provider/multictladdr/multiaddresses.go similarity index 83% rename from storage/ctladdr/multiaddresses.go rename to provider/multictladdr/multiaddresses.go index fbb153e84..4f1947729 100644 --- a/storage/ctladdr/multiaddresses.go +++ b/provider/multictladdr/multiaddresses.go @@ -1,21 +1,26 @@ -package ctladdr +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 NodeApi, minerID address.Address, mi api.MinerInfo, use api.AddrUse, goodFunds, minFunds abi.TokenAmount) (address.Address, abi.TokenAmount, error) { +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") @@ -72,5 +77,5 @@ func (as *MultiAddressSelector) AddressFor(ctx context.Context, a NodeApi, miner addrs = append(addrs, mi.Owner) } - return pickAddress(ctx, a, mi, goodFunds, minFunds, addrs) + 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 From 846daa1788f5b275c07b9d2fd7067ff08fa0c560 Mon Sep 17 00:00:00 2001 From: "Andrew Jackson (Ajax)" Date: Mon, 12 Feb 2024 19:27:55 -0600 Subject: [PATCH 5/5] docsgen --- build/openrpc/full.json.gz | Bin 34617 -> 34608 bytes build/openrpc/gateway.json.gz | Bin 11884 -> 11872 bytes documentation/en/api-v0-methods.md | 1 - documentation/en/api-v1-unstable-methods.md | 1 - 4 files changed, 2 deletions(-) diff --git a/build/openrpc/full.json.gz b/build/openrpc/full.json.gz index a08ffb3f05df7d68dcc3304ffc5c2912d69cf863..3c30e81a9427867a286d476b5eb52110c995bcae 100644 GIT binary patch delta 8075 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 Z`e5Vx_ix|-e*gdg|Ns3dZ5B@P1_0r8#q|IH delta 8033 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 diff --git a/build/openrpc/gateway.json.gz b/build/openrpc/gateway.json.gz index 39055fc6affd76e88bfc885a3f1708e95c5656e3..82d638d7e432e35816cbd7fe44b39594f9c6a5f9 100644 GIT binary patch delta 2572 zcmV+n3iI{sT;N==NhE)wD*o}{rd6^po`08qatR;u4@0u`J%^!I7IkR*;|XxbFs&$E zLFk{`=D_T9PkO(5-j}l&xQf(TAJv$KcdEyIuGf zpYDJEKRhy9=EdB>C`9biQfFU~YkLn@-VMI;J#TbN_WU50C`5lJ==FQMhx@&Q-rhl~ z1Mo5VdbDjoi@qFtZUEh29((|E2cJ4%Mv5253nEFVWFK<{VOr)9bm0hDh<=Bn$G6ZY zqUX=KhXGSsKL^m}f9JF7;(-ewUBZWwVK3nW5B3s1URB|ur4v?k9uQ^5r<<)kK4?Wvfoif#cZAhM!nSvr?pafbYbs`SSU zWPPMA7Es0PCHp7RMW~}9HW!G}*B0Wu+wOl>mDHklmUs^ZzE5GRgmhoC z6l4NO%rGHMYjkPz>(J(iHb=JUy)Gxg^gF=-IppPN>YY%jsJZV$ z7iax%KJx5z*6O)y!v*zq{V{`yBk0)i0+{@o0LOvuIC(;x5yx}vjYjdaFT^w=gG6M+ z+-P5z(G*e`ZIJF1!>1-z$;(fkcQ*vqU3wBH&~kqOwPREBkxj!*mMG*}q5C7$H1#b+ zdZad2xI@84i1cL`Akvg#h|r-bk7`0Da>5*QF+Nw^e@OcI3p(zy0sRn@3Vh#x%vj$C-J!mzpi1-$yL z@y4c<$+cU_iMh5FOgIl%o)xEOzisYYM4S0l+`entI!6HHgLA+Tul%^?_5p26ESbn zH^J3=eO(k~FCA33-D}}iBm?lbk-pf2x5KI`AlGo_fTbd{54#E~mW0z=$lf_dcF2F> z&)s{^x+eH9z~aM!>g4Zi;!R}knq4Z$7=~D@mB2!-k%o1QY{L(S56EW*MgX1BJKAQ5 z+%d&=7e~4bv<(zP+cC~@s7sDKe+q45xHNzf8&JRqnV4m~d6*z;Vj$N>;S$3!rgH}) zD}4KI2CO@1$D@Rs_0|BcZ2*G=vrcG0Fxg4#sP%k)RRghGyz zN6A~(kW5HcWMd-6AQVi(IEP|-QHr^UjF+&RqKMv**-7WyQrl0L^-PXB)7q5uu(9HQC7oJV zpx#MGax*MD33oLtUJhqjXs%pF{F`y-> zSc#FROh(zu-eiOT$JRD1FH}wVr-+Tl7>$}BQ$Om#Wb zHx55_EMEyh=hd$Ah9XK>3Y|hF=mwI7c_UU*5IE4TwYWAd_RiI1Cy7t#0(}KF`@(Kt zn4UonUHR(1sTb!i!U#BjR}QqtFextxEe!1wu)Ky3z_&Bcqk_YH9}?(gL7Q&TdoC?J zdXt4lTmBB0wQkrA3P0DM@73$K@H;GY_hj^mxbsN?1|o1!m^tp_znye_?))cJ1(Ess z3Sgv4%w-T%{&*pWeX1Zh)D|mQ9rFg!<}ve-jJ(ZIl1lH0sfpcxZknR8q7%^~e)GC@ z=5AFX?WFKHf-Vjp&DCxqEdsP=f(X&07|jb+vn!fIeadpl3Y!>T{JivKt#C>xoLQpC zYnlZu1ipUzHQgV$+v!ym@?@0mug?zsCuM~GhFGAlnV)8Un)y9j=GU*P()a}+tQrEq z`j)Y~qB>a=w7Za?v)hQR4iOoUaab^@#g*2xj-$d)%B+mI8r62lDRdZ+*-1T+#aW1 ziAa<ZdqD<8!yNm`4hH1%dMLq)0S7|EAT0Yn=P3h_mp!U*eLA zUuyqJmM#xUsycpw!yY{yQWT9j0L4O*^1DhZ%mON=#Bb&|Q;PNq=GO#4$pk=lx8uhG iD4ddtFRTm~Y3HzKK0bbb{C@!e0RR7cYS-^;jRF7%3JfFw delta 2623 zcmV-F3c&T?Tr`g87K!1UP90krww`GmW8-~vdO@S$YbOZdQpy@U@r$Sw2zZ039S&^}tG zpiq=eUS4`r%+y2C&&34(2y>?FBQxPGDe5)>4fex6W8FGR`B zf;~ts5{cM}bp2G0h`HG)6?o51isM$&_YzQEC~XxmmR4|COgW9pRE{d9$D$iW3aGQF zS(ZV_t~kRtgev~WoM(M%C}g?Pb{HoPL>5pbB_#VNVo86fqarpJ$l%u&F1_3CR+Z1R%+M(+iS-oSU%p^-8HtSYKqP zxA^(4k=OfQfXTYAjHe66A*&j2Qc#w`AFM!Ff32+?fj*}1 z-e?p*`$9}3GDt*5%>VX<8BHOD(FW;GF??!bmArravTJ+$tz<>Sf7 z6>1Y6W^ z8*3P+r46LMPdPev+0XHcss1BC~^&F4p=HO`>=nj zpkhfly@l+ZV`PUM{@lIytZRb*0xUips80UQCf-EmuGyu6jA4kiS_v%V8fjR^$Ts|N z_<($7UoFdhq~m*^QX`@hD!q&u>l2)kcnBwn}-Rq zCI)hC6fQ9wV>)**vck9TX280Gc07MdxLI!v;MxW-NHFUJ1e2Y#j#|&>S2eH;1sO-* zc}bRjDHLxLjKl9+oA|m2#v!oCcp!eiTaS-l|KNMmR6KifTkBuInMYFf396FMxj!c(M$} zyNkQU?B9{weHd9k_NMpU$<({U4?}x#2NwN+2(yb|d~IPGkB%^vqwSV?O_*cx1kOP4 znS^~Gw#?J}kPfar57)K*k7R&jFCY*vU=Vr8q;`m z5=0RCj&Ku-k_j4yzd{4%57&t^DZ+*|l8+ir(RcBj84^r@KV~$3Nm&QwJ;puRm6nOe z1Pd+tS3v*5*c|M&WLct`Ab10@4rI?GzcnP~His%iQopkO#Wr^zt;U;`aDqSvOX=1CV zJWp}AQ*2QU^%K^YaDjguMHF@9v>z$g38%>@VEyMnzNS@+SI^|AGp$WY4;w39(y4U? z>Ya2XH`DWE`*A8^Ei@#FA<7IfvRXFFOL=oh9u39$Ff-M*z_Pc-V_S)-s>Z7l16q=b zl^A)-WR$%)PDTiDY;D65sbL1!=I{Dd1Wxv#60$pV`*K{J_fg#;sCb-C(Jr>a~v%?mh# zSh>hx3W7{{TPUk&XDV*WE-juS7y7K_A1;w@LOI8&iPfpurq`>lFs?(T%p$|aRF^}2 zd+}4p@|6&DUhOJxD58X=&?!`cZXj8hH)6F2fdlPY3w3|f!tq>@V#0 zh3OgO(3P(goO*HYB8-4@xSK+@N@n7UcG(`zr#ZJSVo_SJD(I_AOZ)4nd3hG+ez2@&VN!>5Sg#9 z07k0BTn2wZ<&PI~*ry7DLv6A0*D-GpZ5}fZ$;jIbC8_j|n3~v4sVN#OIuR}6H?Lb~ z?p77$PKuZ#=;H9vT3)G@oU4JTpBUN%LnOhUettE@d?Q!ar zh(v#hL(8)ndmN-er`I{?w_E0s<5_nn&;d#n5;=e(^v(|^c<*KmyoC5)2;uFQ)JFUQ z9H;y){uShx>MZD(dTYF)eu^VBK6fjNd8EKs5GW5%ibS*XZ(2RL#<`!0I19h~B`&G> zrS_j>>GGhYs^b?p?9tO9MbVf8P%I=VzpFQ-!YrU-O8jPiGo@&+V17*yluQ6*cRPM8 hfWj%M_`=GNb`E>y