miner: Control address config for (pre)commits

This commit is contained in:
Łukasz Magiera 2020-12-02 19:58:00 +01:00
parent 3196b2cfd5
commit 7246ef273f
7 changed files with 106 additions and 13 deletions

View File

@ -357,6 +357,7 @@ func Online() Option {
Override(new(*sectorblocks.SectorBlocks), sectorblocks.NewSectorBlocks), Override(new(*sectorblocks.SectorBlocks), sectorblocks.NewSectorBlocks),
Override(new(*storage.Miner), modules.StorageMiner(config.DefaultStorageMiner().Fees)), Override(new(*storage.Miner), modules.StorageMiner(config.DefaultStorageMiner().Fees)),
Override(new(*storage.AddressSelector), modules.AddressSelector(nil)),
Override(new(dtypes.NetworkName), modules.StorageNetworkName), Override(new(dtypes.NetworkName), modules.StorageNetworkName),
Override(new(dtypes.StagingMultiDstore), modules.StagingMultiDatastore), Override(new(dtypes.StagingMultiDstore), modules.StagingMultiDatastore),
@ -511,6 +512,7 @@ func ConfigStorageMiner(c interface{}) Option {
Override(new(storagemarket.StorageProviderNode), storageadapter.NewProviderNodeAdapter(&cfg.Fees)), Override(new(storagemarket.StorageProviderNode), storageadapter.NewProviderNodeAdapter(&cfg.Fees)),
Override(new(sectorstorage.SealerConfig), cfg.Storage), Override(new(sectorstorage.SealerConfig), cfg.Storage),
Override(new(*storage.AddressSelector), modules.AddressSelector(&cfg.Addresses)),
Override(new(*storage.Miner), modules.StorageMiner(cfg.Fees)), Override(new(*storage.Miner), modules.StorageMiner(cfg.Fees)),
) )
} }

View File

@ -36,6 +36,7 @@ type StorageMiner struct {
Sealing SealingConfig Sealing SealingConfig
Storage sectorstorage.SealerConfig Storage sectorstorage.SealerConfig
Fees MinerFeeConfig Fees MinerFeeConfig
Addresses MinerAddressConfig
} }
type DealmakingConfig struct { type DealmakingConfig struct {
@ -71,6 +72,11 @@ type MinerFeeConfig struct {
MaxMarketBalanceAddFee types.FIL MaxMarketBalanceAddFee types.FIL
} }
type MinerAddressConfig struct {
PreCommitControl []string
CommitControl []string
}
// API contains configs for API endpoint // API contains configs for API endpoint
type API struct { type API struct {
ListenAddress string ListenAddress string

View File

@ -145,6 +145,35 @@ func SectorIDCounter(ds dtypes.MetadataDS) sealing.SectorIDCounter {
return &sidsc{sc} return &sidsc{sc}
} }
func AddressSelector(addrConf *config.MinerAddressConfig) func() (*storage.AddressSelector, error) {
return func() (*storage.AddressSelector, error) {
as := &storage.AddressSelector{}
if addrConf == nil {
return as, nil
}
for _, s := range addrConf.PreCommitControl {
addr, err := address.NewFromString(s)
if err != nil {
return nil, xerrors.Errorf("parsing precommit control address: %w", err)
}
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)
}
return as, nil
}
}
type StorageMinerParams struct { type StorageMinerParams struct {
fx.In fx.In
@ -158,6 +187,7 @@ type StorageMinerParams struct {
Verifier ffiwrapper.Verifier Verifier ffiwrapper.Verifier
GetSealingConfigFn dtypes.GetSealingConfigFunc GetSealingConfigFn dtypes.GetSealingConfigFunc
Journal journal.Journal Journal journal.Journal
AddrSel *storage.AddressSelector
} }
func StorageMiner(fc config.MinerFeeConfig) func(params StorageMinerParams) (*storage.Miner, error) { func StorageMiner(fc config.MinerFeeConfig) func(params StorageMinerParams) (*storage.Miner, error) {
@ -173,6 +203,7 @@ func StorageMiner(fc config.MinerFeeConfig) func(params StorageMinerParams) (*st
verif = params.Verifier verif = params.Verifier
gsd = params.GetSealingConfigFn gsd = params.GetSealingConfigFn
j = params.Journal j = params.Journal
as = params.AddrSel
) )
maddr, err := minerAddrFromDS(ds) maddr, err := minerAddrFromDS(ds)
@ -182,7 +213,7 @@ func StorageMiner(fc config.MinerFeeConfig) func(params StorageMinerParams) (*st
ctx := helpers.LifecycleCtx(mctx, lc) ctx := helpers.LifecycleCtx(mctx, lc)
fps, err := storage.NewWindowedPoStScheduler(api, fc, sealer, sealer, j, maddr) fps, err := storage.NewWindowedPoStScheduler(api, fc, as, sealer, sealer, j, maddr)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -5,8 +5,6 @@ import (
"github.com/filecoin-project/go-address" "github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/lotus/chain/actors/builtin/miner" "github.com/filecoin-project/lotus/chain/actors/builtin/miner"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
) )
@ -24,19 +22,72 @@ type addrSelectApi interface {
WalletHas(context.Context, address.Address) (bool, error) WalletHas(context.Context, address.Address) (bool, error)
StateAccountKey(context.Context, address.Address, types.TipSetKey) (address.Address, error) StateAccountKey(context.Context, address.Address, types.TipSetKey) (address.Address, error)
StateLookupID(context.Context, address.Address, types.TipSetKey) (address.Address, error)
} }
func AddressFor(ctx context.Context, a addrSelectApi, mi miner.MinerInfo, use AddrUse, goodFunds, minFunds abi.TokenAmount) (address.Address, abi.TokenAmount, error) { type AddressSelector struct {
switch use { PreCommitControl []address.Address
case PreCommitAddr, CommitAddr: CommitControl []address.Address
// always use worker, at least for now }
return mi.Worker, big.Zero(), nil
}
func (as *AddressSelector) AddressFor(ctx context.Context, a addrSelectApi, mi miner.MinerInfo, use AddrUse, goodFunds, minFunds abi.TokenAmount) (address.Address, abi.TokenAmount, error) {
var addrs []address.Address
switch use {
case PreCommitAddr:
addrs = append(addrs, as.PreCommitControl...)
case CommitAddr:
addrs = append(addrs, as.CommitControl...)
default:
defaultCtl := map[address.Address]struct{}{}
for _, a := range mi.ControlAddresses {
defaultCtl[a] = struct{}{}
}
delete(defaultCtl, mi.Owner)
delete(defaultCtl, mi.Worker)
for _, addr := range append(append([]address.Address{}, as.PreCommitControl...), as.CommitControl...) {
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)
}
}
addrs = append(addrs, mi.Owner, mi.Worker)
return pickAddress(ctx, a, mi, goodFunds, minFunds, addrs)
}
func pickAddress(ctx context.Context, a addrSelectApi, mi miner.MinerInfo, goodFunds, minFunds abi.TokenAmount, addrs []address.Address) (address.Address, abi.TokenAmount, error) {
leastBad := mi.Worker leastBad := mi.Worker
bestAvail := minFunds bestAvail := minFunds
for _, addr := range append(mi.ControlAddresses, mi.Owner, mi.Worker) { ctl := map[address.Address]struct{}{}
for _, a := range append(mi.ControlAddresses, mi.Owner, mi.Worker) {
ctl[a] = struct{}{}
}
for _, addr := range addrs {
addr, err := a.StateLookupID(ctx, addr, types.EmptyTSK)
if err != nil {
log.Warnw("looking up control address", "address", addr, "error", err)
continue
}
if _, ok := ctl[addr]; !ok {
log.Warnw("non-control address configured for sending messages", "address", addr)
continue
}
if maybeUseAddress(ctx, a, addr, goodFunds, &leastBad, &bestAvail) { if maybeUseAddress(ctx, a, addr, goodFunds, &leastBad, &bestAvail) {
return leastBad, bestAvail, nil return leastBad, bestAvail, nil
} }
@ -68,7 +119,7 @@ func maybeUseAddress(ctx context.Context, a addrSelectApi, addr address.Address,
} }
if !have { if !have {
log.Errorw("don't have key", "key", k) log.Errorw("don't have key", "key", k, "address", addr)
return false return false
} }

View File

@ -91,6 +91,7 @@ type storageMinerApi interface {
StateMinerRecoveries(context.Context, address.Address, types.TipSetKey) (bitfield.BitField, error) StateMinerRecoveries(context.Context, address.Address, types.TipSetKey) (bitfield.BitField, error)
StateAccountKey(context.Context, address.Address, types.TipSetKey) (address.Address, error) StateAccountKey(context.Context, address.Address, types.TipSetKey) (address.Address, error)
StateNetworkVersion(context.Context, types.TipSetKey) (network.Version, error) StateNetworkVersion(context.Context, types.TipSetKey) (network.Version, error)
StateLookupID(context.Context, address.Address, types.TipSetKey) (address.Address, error)
MpoolPushMessage(context.Context, *types.Message, *api.MessageSendSpec) (*types.SignedMessage, error) MpoolPushMessage(context.Context, *types.Message, *api.MessageSendSpec) (*types.SignedMessage, error)

View File

@ -799,7 +799,7 @@ func (s *WindowPoStScheduler) setSender(ctx context.Context, msg *types.Message,
goodFunds := big.Add(msg.RequiredFunds(), msg.Value) goodFunds := big.Add(msg.RequiredFunds(), msg.Value)
minFunds := big.Min(big.Add(minGasFeeMsg.RequiredFunds(), minGasFeeMsg.Value), goodFunds) minFunds := big.Min(big.Add(minGasFeeMsg.RequiredFunds(), minGasFeeMsg.Value), goodFunds)
pa, avail, err := AddressFor(ctx, s.api, mi, PoStAddr, goodFunds, minFunds) pa, avail, err := s.addrSel.AddressFor(ctx, s.api, mi, PoStAddr, goodFunds, minFunds)
if err != nil { if err != nil {
log.Errorw("error selecting address for window post", "error", err) log.Errorw("error selecting address for window post", "error", err)
return nil return nil

View File

@ -25,6 +25,7 @@ import (
type WindowPoStScheduler struct { type WindowPoStScheduler struct {
api storageMinerApi api storageMinerApi
feeCfg config.MinerFeeConfig feeCfg config.MinerFeeConfig
addrSel *AddressSelector
prover storage.Prover prover storage.Prover
faultTracker sectorstorage.FaultTracker faultTracker sectorstorage.FaultTracker
proofType abi.RegisteredPoStProof proofType abi.RegisteredPoStProof
@ -40,7 +41,7 @@ type WindowPoStScheduler struct {
// failLk sync.Mutex // failLk sync.Mutex
} }
func NewWindowedPoStScheduler(api storageMinerApi, fc config.MinerFeeConfig, sb storage.Prover, ft sectorstorage.FaultTracker, j journal.Journal, actor address.Address) (*WindowPoStScheduler, error) { func NewWindowedPoStScheduler(api storageMinerApi, fc config.MinerFeeConfig, as *AddressSelector, sb storage.Prover, ft sectorstorage.FaultTracker, j journal.Journal, actor address.Address) (*WindowPoStScheduler, error) {
mi, err := api.StateMinerInfo(context.TODO(), actor, types.EmptyTSK) mi, err := api.StateMinerInfo(context.TODO(), actor, types.EmptyTSK)
if err != nil { if err != nil {
return nil, xerrors.Errorf("getting sector size: %w", err) return nil, xerrors.Errorf("getting sector size: %w", err)
@ -54,6 +55,7 @@ func NewWindowedPoStScheduler(api storageMinerApi, fc config.MinerFeeConfig, sb
return &WindowPoStScheduler{ return &WindowPoStScheduler{
api: api, api: api,
feeCfg: fc, feeCfg: fc,
addrSel: as,
prover: sb, prover: sb,
faultTracker: ft, faultTracker: ft,
proofType: rt, proofType: rt,