diff --git a/extern/storage-fsm/sealing.go b/extern/storage-fsm/sealing.go index d15255696..a18a0b0b7 100644 --- a/extern/storage-fsm/sealing.go +++ b/extern/storage-fsm/sealing.go @@ -45,7 +45,7 @@ type SealingAPI interface { StateMinerPreCommitDepositForPower(context.Context, address.Address, miner.SectorPreCommitInfo, TipSetToken) (big.Int, error) StateMinerInitialPledgeCollateral(context.Context, address.Address, miner.SectorPreCommitInfo, TipSetToken) (big.Int, error) StateMarketStorageDeal(context.Context, abi.DealID, TipSetToken) (market.DealProposal, error) - SendMsg(ctx context.Context, from, to address.Address, method abi.MethodNum, value, gasPrice big.Int, gasLimit int64, params []byte) (cid.Cid, error) + SendMsg(ctx context.Context, from, to address.Address, method abi.MethodNum, value, maxFee abi.TokenAmount, params []byte) (cid.Cid, error) ChainHead(ctx context.Context) (TipSetToken, abi.ChainEpoch, error) ChainGetRandomness(ctx context.Context, tok TipSetToken, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) (abi.Randomness, error) ChainReadObj(context.Context, cid.Cid) ([]byte, error) @@ -53,6 +53,7 @@ type SealingAPI interface { type Sealing struct { api SealingAPI + feeCfg FeeConfig events Events maddr address.Address @@ -71,6 +72,11 @@ type Sealing struct { getSealDelay GetSealingDelayFunc } +type FeeConfig struct { + MaxPreCommitGasFee abi.TokenAmount + MaxCommitGasFee abi.TokenAmount +} + type UnsealedSectorMap struct { infos map[abi.SectorNumber]UnsealedSectorInfo mux sync.Mutex @@ -83,9 +89,10 @@ type UnsealedSectorInfo struct { pieceSizes []abi.UnpaddedPieceSize } -func New(api SealingAPI, events Events, maddr address.Address, ds datastore.Batching, sealer sectorstorage.SectorManager, sc SectorIDCounter, verif ffiwrapper.Verifier, pcp PreCommitPolicy, gsd GetSealingDelayFunc) *Sealing { +func New(api SealingAPI, fc FeeConfig, events Events, maddr address.Address, ds datastore.Batching, sealer sectorstorage.SectorManager, sc SectorIDCounter, verif ffiwrapper.Verifier, pcp PreCommitPolicy, gsd GetSealingDelayFunc) *Sealing { s := &Sealing{ api: api, + feeCfg: fc, events: events, maddr: maddr, diff --git a/extern/storage-fsm/states_sealing.go b/extern/storage-fsm/states_sealing.go index 11e8a39a5..d307b7638 100644 --- a/extern/storage-fsm/states_sealing.go +++ b/extern/storage-fsm/states_sealing.go @@ -184,7 +184,7 @@ func (m *Sealing) handlePreCommitting(ctx statemachine.Context, sector SectorInf deposit := big.Max(depositMinimum, collateral) log.Infof("submitting precommit for sector %d (deposit: %s): ", sector.SectorNumber, deposit) - mcid, err := m.api.SendMsg(ctx.Context(), waddr, m.maddr, builtin.MethodsMiner.PreCommitSector, deposit, big.NewInt(0), 0, enc.Bytes()) + mcid, err := m.api.SendMsg(ctx.Context(), waddr, m.maddr, builtin.MethodsMiner.PreCommitSector, deposit, m.feeCfg.MaxPreCommitGasFee, enc.Bytes()) if err != nil { return ctx.Send(SectorChainPreCommitFailed{xerrors.Errorf("pushing message to mpool: %w", err)}) } @@ -333,7 +333,7 @@ func (m *Sealing) handleCommitting(ctx statemachine.Context, sector SectorInfo) } // TODO: check seed / ticket are up to date - mcid, err := m.api.SendMsg(ctx.Context(), waddr, m.maddr, builtin.MethodsMiner.ProveCommitSector, collateral, big.NewInt(0), 0, enc.Bytes()) + mcid, err := m.api.SendMsg(ctx.Context(), waddr, m.maddr, builtin.MethodsMiner.ProveCommitSector, collateral, m.feeCfg.MaxCommitGasFee, enc.Bytes()) if err != nil { return ctx.Send(SectorCommitFailed{xerrors.Errorf("pushing message to mpool: %w", err)}) } diff --git a/node/builder.go b/node/builder.go index aa0a18626..f70072596 100644 --- a/node/builder.go +++ b/node/builder.go @@ -302,7 +302,7 @@ func Online() Option { Override(new(storage2.Prover), From(new(sectorstorage.SectorManager))), Override(new(*sectorblocks.SectorBlocks), sectorblocks.NewSectorBlocks), - Override(new(*storage.Miner), modules.StorageMiner), + Override(new(*storage.Miner), modules.StorageMiner(config.DefaultStorageMiner().Fees)), Override(new(dtypes.NetworkName), modules.StorageNetworkName), Override(new(dtypes.StagingMultiDstore), modules.StagingMultiDatastore), @@ -439,6 +439,7 @@ func ConfigStorageMiner(c interface{}) Option { ), Override(new(sectorstorage.SealerConfig), cfg.Storage), + Override(new(*storage.Miner), modules.StorageMiner(cfg.Fees)), ) } diff --git a/node/config/def.go b/node/config/def.go index b967ed6c3..4fd5a5bd2 100644 --- a/node/config/def.go +++ b/node/config/def.go @@ -7,6 +7,8 @@ import ( "github.com/ipfs/go-cid" sectorstorage "github.com/filecoin-project/sector-storage" + + "github.com/filecoin-project/lotus/chain/types" ) // Common is common config between full node and miner @@ -29,8 +31,10 @@ type FullNode struct { type StorageMiner struct { Common - Dealmaking DealmakingConfig - Storage sectorstorage.SealerConfig + Dealmaking DealmakingConfig + Storage sectorstorage.SealerConfig + Fees MinerFeeConfig + SealingDelay Duration } @@ -45,6 +49,12 @@ type DealmakingConfig struct { Filter string } +type MinerFeeConfig struct { + MaxPreCommitGasFee types.FIL + MaxCommitGasFee types.FIL + MaxWindowPoStGasFee types.FIL +} + // API contains configs for API endpoint type API struct { ListenAddress string @@ -143,6 +153,12 @@ func DefaultStorageMiner() *StorageMiner { ExpectedSealDuration: Duration(time.Hour * 12), }, + Fees: MinerFeeConfig{ + MaxPreCommitGasFee: types.FIL(types.FromFil(1)), + MaxCommitGasFee: types.FIL(types.FromFil(1)), + MaxWindowPoStGasFee: types.FIL(types.FromFil(50)), + }, + SealingDelay: Duration(time.Hour), } cfg.Common.API.ListenAddress = "/ip4/127.0.0.1/tcp/2345/http" diff --git a/node/modules/storageminer.go b/node/modules/storageminer.go index a0956d31c..ebb0c4986 100644 --- a/node/modules/storageminer.go +++ b/node/modules/storageminer.go @@ -142,43 +142,45 @@ func SectorIDCounter(ds dtypes.MetadataDS) sealing.SectorIDCounter { return &sidsc{sc} } -func StorageMiner(mctx helpers.MetricsCtx, lc fx.Lifecycle, api lapi.FullNode, h host.Host, ds dtypes.MetadataDS, sealer sectorstorage.SectorManager, sc sealing.SectorIDCounter, verif ffiwrapper.Verifier, gsd dtypes.GetSealingDelayFunc) (*storage.Miner, error) { - maddr, err := minerAddrFromDS(ds) - if err != nil { - return nil, err +func StorageMiner(fc config.MinerFeeConfig) func(mctx helpers.MetricsCtx, lc fx.Lifecycle, api lapi.FullNode, h host.Host, ds dtypes.MetadataDS, sealer sectorstorage.SectorManager, sc sealing.SectorIDCounter, verif ffiwrapper.Verifier, gsd dtypes.GetSealingDelayFunc) (*storage.Miner, error) { + return func(mctx helpers.MetricsCtx, lc fx.Lifecycle, api lapi.FullNode, h host.Host, ds dtypes.MetadataDS, sealer sectorstorage.SectorManager, sc sealing.SectorIDCounter, verif ffiwrapper.Verifier, gsd dtypes.GetSealingDelayFunc) (*storage.Miner, error) { + maddr, err := minerAddrFromDS(ds) + if err != nil { + return nil, err + } + + ctx := helpers.LifecycleCtx(mctx, lc) + + mi, err := api.StateMinerInfo(ctx, maddr, types.EmptyTSK) + if err != nil { + return nil, err + } + + worker, err := api.StateAccountKey(ctx, mi.Worker, types.EmptyTSK) + if err != nil { + return nil, err + } + + fps, err := storage.NewWindowedPoStScheduler(api, fc, sealer, sealer, maddr, worker) + if err != nil { + return nil, err + } + + sm, err := storage.NewMiner(api, maddr, worker, h, ds, sealer, sc, verif, gsd, fc) + if err != nil { + return nil, err + } + + lc.Append(fx.Hook{ + OnStart: func(context.Context) error { + go fps.Run(ctx) + return sm.Run(ctx) + }, + OnStop: sm.Stop, + }) + + return sm, nil } - - ctx := helpers.LifecycleCtx(mctx, lc) - - mi, err := api.StateMinerInfo(ctx, maddr, types.EmptyTSK) - if err != nil { - return nil, err - } - - worker, err := api.StateAccountKey(ctx, mi.Worker, types.EmptyTSK) - if err != nil { - return nil, err - } - - fps, err := storage.NewWindowedPoStScheduler(api, sealer, sealer, maddr, worker) - if err != nil { - return nil, err - } - - sm, err := storage.NewMiner(api, maddr, worker, h, ds, sealer, sc, verif, gsd) - if err != nil { - return nil, err - } - - lc.Append(fx.Hook{ - OnStart: func(context.Context) error { - go fps.Run(ctx) - return sm.Run(ctx) - }, - OnStop: sm.Stop, - }) - - return sm, nil } func HandleRetrieval(host host.Host, lc fx.Lifecycle, m retrievalmarket.RetrievalProvider) { diff --git a/storage/adapter_storage_miner.go b/storage/adapter_storage_miner.go index 361127943..8938996eb 100644 --- a/storage/adapter_storage_miner.go +++ b/storage/adapter_storage_miner.go @@ -237,19 +237,16 @@ func (s SealingAPIAdapter) StateMarketStorageDeal(ctx context.Context, dealID ab return deal.Proposal, nil } -//TODO: rename/remove gasPrice and gasLimit -func (s SealingAPIAdapter) SendMsg(ctx context.Context, from, to address.Address, method abi.MethodNum, value, gasPrice big.Int, gasLimit int64, params []byte) (cid.Cid, error) { +func (s SealingAPIAdapter) SendMsg(ctx context.Context, from, to address.Address, method abi.MethodNum, value, maxFee abi.TokenAmount, params []byte) (cid.Cid, error) { msg := types.Message{ - To: to, - From: from, - Value: value, - GasPremium: gasPrice, - GasLimit: gasLimit, - Method: method, - Params: params, + To: to, + From: from, + Value: value, + Method: method, + Params: params, } - smsg, err := s.delegate.MpoolPushMessage(ctx, &msg, big.Zero()) + smsg, err := s.delegate.MpoolPushMessage(ctx, &msg, maxFee) if err != nil { return cid.Undef, err } diff --git a/storage/miner.go b/storage/miner.go index 4346757cb..9d81f7e6c 100644 --- a/storage/miner.go +++ b/storage/miner.go @@ -24,6 +24,7 @@ import ( "github.com/filecoin-project/lotus/chain/events" "github.com/filecoin-project/lotus/chain/gen" "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/lotus/node/config" "github.com/filecoin-project/lotus/node/modules/dtypes" sealing "github.com/filecoin-project/storage-fsm" ) @@ -32,6 +33,7 @@ var log = logging.Logger("storageminer") type Miner struct { api storageMinerApi + feeCfg config.MinerFeeConfig h host.Host sealer sectorstorage.SectorManager ds datastore.Batching @@ -81,9 +83,10 @@ type storageMinerApi interface { WalletHas(context.Context, address.Address) (bool, error) } -func NewMiner(api storageMinerApi, maddr, worker address.Address, h host.Host, ds datastore.Batching, sealer sectorstorage.SectorManager, sc sealing.SectorIDCounter, verif ffiwrapper.Verifier, gsd dtypes.GetSealingDelayFunc) (*Miner, error) { +func NewMiner(api storageMinerApi, maddr, worker address.Address, h host.Host, ds datastore.Batching, sealer sectorstorage.SectorManager, sc sealing.SectorIDCounter, verif ffiwrapper.Verifier, gsd dtypes.GetSealingDelayFunc, feeCfg config.MinerFeeConfig) (*Miner, error) { m := &Miner{ api: api, + feeCfg: feeCfg, h: h, sealer: sealer, ds: ds, @@ -108,10 +111,15 @@ func (m *Miner) Run(ctx context.Context) error { return xerrors.Errorf("getting miner info: %w", err) } + fc := sealing.FeeConfig{ + MaxPreCommitGasFee: abi.TokenAmount(m.feeCfg.MaxPreCommitGasFee), + MaxCommitGasFee: abi.TokenAmount(m.feeCfg.MaxCommitGasFee), + } + evts := events.NewEvents(ctx, m.api) adaptedAPI := NewSealingAPIAdapter(m.api) pcp := sealing.NewBasicPreCommitPolicy(adaptedAPI, miner.MaxSectorExpirationExtension-(miner.WPoStProvingPeriod*2), md.PeriodStart%miner.WPoStProvingPeriod) - m.sealing = sealing.New(adaptedAPI, NewEventsAdapter(evts), m.maddr, m.ds, m.sealer, m.sc, m.verif, &pcp, sealing.GetSealingDelayFunc(m.getSealDelay)) + m.sealing = sealing.New(adaptedAPI, fc, NewEventsAdapter(evts), m.maddr, m.ds, m.sealer, m.sc, m.verif, &pcp, sealing.GetSealingDelayFunc(m.getSealDelay)) go m.sealing.Run(ctx) //nolint:errcheck // logged intside the function diff --git a/storage/wdpost_run.go b/storage/wdpost_run.go index 04ffe2606..c91db9441 100644 --- a/storage/wdpost_run.go +++ b/storage/wdpost_run.go @@ -10,7 +10,6 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/specs-actors/actors/abi" - "github.com/filecoin-project/specs-actors/actors/abi/big" "github.com/filecoin-project/specs-actors/actors/builtin" "github.com/filecoin-project/specs-actors/actors/builtin/miner" "github.com/filecoin-project/specs-actors/actors/crypto" @@ -178,7 +177,7 @@ func (s *WindowPoStScheduler) checkNextRecoveries(ctx context.Context, dlIdx uin Value: types.NewInt(0), } - sm, err := s.api.MpoolPushMessage(ctx, msg, big.Zero()) + sm, err := s.api.MpoolPushMessage(ctx, msg, abi.TokenAmount(s.feeCfg.MaxWindowPoStGasFee)) if err != nil { return xerrors.Errorf("pushing message to mpool: %w", err) } @@ -260,7 +259,7 @@ func (s *WindowPoStScheduler) checkNextFaults(ctx context.Context, dlIdx uint64, Value: types.NewInt(0), // TODO: Is there a fee? } - sm, err := s.api.MpoolPushMessage(ctx, msg, big.Zero()) + sm, err := s.api.MpoolPushMessage(ctx, msg, abi.TokenAmount(s.feeCfg.MaxWindowPoStGasFee)) if err != nil { return xerrors.Errorf("pushing message to mpool: %w", err) } @@ -457,7 +456,7 @@ func (s *WindowPoStScheduler) submitPost(ctx context.Context, proof *miner.Submi } // TODO: consider maybe caring about the output - sm, err := s.api.MpoolPushMessage(ctx, msg, big.Zero()) + sm, err := s.api.MpoolPushMessage(ctx, msg, abi.TokenAmount(s.feeCfg.MaxWindowPoStGasFee)) if err != nil { return xerrors.Errorf("pushing message to mpool: %w", err) } diff --git a/storage/wdpost_sched.go b/storage/wdpost_sched.go index 8e3221ef9..8adfe2f76 100644 --- a/storage/wdpost_sched.go +++ b/storage/wdpost_sched.go @@ -2,6 +2,7 @@ package storage import ( "context" + "github.com/filecoin-project/lotus/node/config" "time" "go.opencensus.io/trace" @@ -23,6 +24,7 @@ const StartConfidence = 4 // TODO: config type WindowPoStScheduler struct { api storageMinerApi + feeCfg config.MinerFeeConfig prover storage.Prover faultTracker sectorstorage.FaultTracker proofType abi.RegisteredPoStProof @@ -41,7 +43,7 @@ type WindowPoStScheduler struct { //failLk sync.Mutex } -func NewWindowedPoStScheduler(api storageMinerApi, sb storage.Prover, ft sectorstorage.FaultTracker, actor address.Address, worker address.Address) (*WindowPoStScheduler, error) { +func NewWindowedPoStScheduler(api storageMinerApi, fc config.MinerFeeConfig, sb storage.Prover, ft sectorstorage.FaultTracker, actor address.Address, worker address.Address) (*WindowPoStScheduler, error) { mi, err := api.StateMinerInfo(context.TODO(), actor, types.EmptyTSK) if err != nil { return nil, xerrors.Errorf("getting sector size: %w", err) @@ -54,6 +56,7 @@ func NewWindowedPoStScheduler(api storageMinerApi, sb storage.Prover, ft sectors return &WindowPoStScheduler{ api: api, + feeCfg: fc, prover: sb, faultTracker: ft, proofType: rt,