Merge pull request #3005 from filecoin-project/feat/max-msg-fee-config

Miner fee config
This commit is contained in:
Łukasz Magiera 2020-08-12 22:37:15 +02:00 committed by GitHub
commit 8408a56e55
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
37 changed files with 280 additions and 124 deletions

View File

@ -170,7 +170,11 @@ type FullNode interface {
// MpoolPushMessage atomically assigns a nonce, signs, and pushes a message
// to mempool.
MpoolPushMessage(context.Context, *types.Message) (*types.SignedMessage, error)
// maxFee is only used when GasFeeCap/GasPremium fields aren't specified
//
// When maxFee is set to 0, MpoolPushMessage will guess appropriate fee
// based on current chain conditions
MpoolPushMessage(ctx context.Context, msg *types.Message, spec *MessageSendSpec) (*types.SignedMessage, error)
// MpoolGetNonce gets next nonce for the specified sender.
// Note that this method may not be atomic. Use MpoolPushMessage instead.

View File

@ -104,11 +104,11 @@ type FullNodeStruct struct {
MpoolSelect func(context.Context, types.TipSetKey, float64) ([]*types.SignedMessage, error) `perm:"read"`
MpoolPending func(context.Context, types.TipSetKey) ([]*types.SignedMessage, error) `perm:"read"`
MpoolPush func(context.Context, *types.SignedMessage) (cid.Cid, error) `perm:"write"`
MpoolPushMessage func(context.Context, *types.Message) (*types.SignedMessage, error) `perm:"sign"`
MpoolGetNonce func(context.Context, address.Address) (uint64, error) `perm:"read"`
MpoolSub func(context.Context) (<-chan api.MpoolUpdate, error) `perm:"read"`
MpoolPending func(context.Context, types.TipSetKey) ([]*types.SignedMessage, error) `perm:"read"`
MpoolPush func(context.Context, *types.SignedMessage) (cid.Cid, error) `perm:"write"`
MpoolPushMessage func(context.Context, *types.Message, *api.MessageSendSpec) (*types.SignedMessage, error) `perm:"sign"`
MpoolGetNonce func(context.Context, address.Address) (uint64, error) `perm:"read"`
MpoolSub func(context.Context) (<-chan api.MpoolUpdate, error) `perm:"read"`
MinerGetBaseInfo func(context.Context, address.Address, abi.ChainEpoch, types.TipSetKey) (*api.MiningBaseInfo, error) `perm:"read"`
MinerCreateBlock func(context.Context, *api.BlockTemplate) (*types.BlockMsg, error) `perm:"write"`
@ -472,8 +472,8 @@ func (c *FullNodeStruct) MpoolPush(ctx context.Context, smsg *types.SignedMessag
return c.Internal.MpoolPush(ctx, smsg)
}
func (c *FullNodeStruct) MpoolPushMessage(ctx context.Context, msg *types.Message) (*types.SignedMessage, error) {
return c.Internal.MpoolPushMessage(ctx, msg)
func (c *FullNodeStruct) MpoolPushMessage(ctx context.Context, msg *types.Message, spec *api.MessageSendSpec) (*types.SignedMessage, error) {
return c.Internal.MpoolPushMessage(ctx, msg, spec)
}
func (c *FullNodeStruct) MpoolSub(ctx context.Context) (<-chan api.MpoolUpdate, error) {

View File

@ -221,7 +221,7 @@ func waitForBlocks(ctx context.Context, t *testing.T, bm *blockMiner, paymentRec
To: builtin.BurntFundsActorAddr,
From: receiverAddr,
Value: types.NewInt(0),
})
}, nil)
if err != nil {
t.Fatal(err)
}
@ -307,7 +307,7 @@ func sendFunds(ctx context.Context, t *testing.T, sender TestNode, addr address.
Value: amount,
}
sm, err := sender.MpoolPushMessage(ctx, msg)
sm, err := sender.MpoolPushMessage(ctx, msg, nil)
if err != nil {
t.Fatal(err)
}

View File

@ -4,6 +4,7 @@ import (
"encoding/json"
"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/miner"
"github.com/libp2p/go-libp2p-core/peer"
@ -76,3 +77,19 @@ func NewApiMinerInfo(info *miner.MinerInfo) MinerInfo {
return mi
}
type MessageSendSpec struct {
MaxFee abi.TokenAmount
}
var DefaultMessageSendSpec = MessageSendSpec{
MaxFee: big.Zero(),
}
func (ms *MessageSendSpec) Get() MessageSendSpec {
if ms == nil {
return DefaultMessageSendSpec
}
return *ms
}

View File

@ -60,7 +60,7 @@ func StartFundManager(lc fx.Lifecycle, api API) *FundMgr {
type fundMgrAPI interface {
StateMarketBalance(context.Context, address.Address, types.TipSetKey) (api.MarketBalance, error)
MpoolPushMessage(context.Context, *types.Message) (*types.SignedMessage, error)
MpoolPushMessage(context.Context, *types.Message, *api.MessageSendSpec) (*types.SignedMessage, error)
StateLookupID(context.Context, address.Address, types.TipSetKey) (address.Address, error)
}
@ -149,7 +149,7 @@ func (fm *FundMgr) EnsureAvailable(ctx context.Context, addr, wallet address.Add
Value: toAdd,
Method: builtin.MethodsMarket.AddBalance,
Params: params,
})
}, nil)
if err != nil {
return cid.Undef, err
}

View File

@ -36,7 +36,7 @@ func (fapi *fakeAPI) StateMarketBalance(context.Context, address.Address, types.
return fapi.returnedBalance, fapi.returnedBalanceErr
}
func (fapi *fakeAPI) MpoolPushMessage(ctx context.Context, msg *types.Message) (*types.SignedMessage, error) {
func (fapi *fakeAPI) MpoolPushMessage(ctx context.Context, msg *types.Message, spec *api.MessageSendSpec) (*types.SignedMessage, error) {
fapi.receivedMessage = msg
return &types.SignedMessage{
Message: *msg,

View File

@ -1,6 +1,7 @@
package types
import (
"encoding"
"fmt"
"math/big"
"strings"
@ -27,6 +28,20 @@ func (f FIL) Format(s fmt.State, ch rune) {
}
}
func (f FIL) MarshalText() (text []byte, err error) {
return []byte(f.String()), nil
}
func (f FIL) UnmarshalText(text []byte) error {
p, err := ParseFIL(string(text))
if err != nil {
return err
}
f.Int.Set(p.Int)
return nil
}
func ParseFIL(s string) (FIL, error) {
suffix := strings.TrimLeft(s, ".1234567890")
s = s[:len(s)-len(suffix)]
@ -61,3 +76,6 @@ func ParseFIL(s string) (FIL, error) {
return FIL{r.Num()}, nil
}
var _ encoding.TextMarshaler = (*FIL)(nil)
var _ encoding.TextUnmarshaler = (*FIL)(nil)

View File

@ -1007,7 +1007,7 @@ var slashConsensusFault = &cli.Command{
Params: enc,
}
smsg, err := api.MpoolPushMessage(ctx, msg)
smsg, err := api.MpoolPushMessage(ctx, msg, nil)
if err != nil {
return err
}

View File

@ -8,13 +8,15 @@ import (
"fmt"
"reflect"
"github.com/urfave/cli/v2"
cbg "github.com/whyrusleeping/cbor-gen"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/chain/stmgr"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/urfave/cli/v2"
cbg "github.com/whyrusleeping/cbor-gen"
)
var sendCmd = &cli.Command{
@ -154,7 +156,7 @@ var sendCmd = &cli.Command{
}
fmt.Println(sm.Cid())
} else {
sm, err := api.MpoolPushMessage(ctx, msg)
sm, err := api.MpoolPushMessage(ctx, msg, nil)
if err != nil {
return err
}

View File

@ -79,7 +79,7 @@ func sendSmallFundsTxs(ctx context.Context, api api.FullNode, from address.Addre
Value: types.NewInt(1),
}
smsg, err := api.MpoolPushMessage(ctx, msg)
smsg, err := api.MpoolPushMessage(ctx, msg, nil)
if err != nil {
return err
}

View File

@ -279,7 +279,7 @@ func (h *handler) send(w http.ResponseWriter, r *http.Request) {
Value: types.BigInt(h.sendPerRequest),
From: h.from,
To: to,
})
}, nil)
if err != nil {
w.WriteHeader(400)
_, _ = w.Write([]byte(err.Error()))
@ -350,7 +350,7 @@ func (h *handler) mkminer(w http.ResponseWriter, r *http.Request) {
Value: types.BigInt(h.sendPerRequest),
From: h.from,
To: owner,
})
}, nil)
if err != nil {
w.WriteHeader(400)
w.Write([]byte("pushfunds: " + err.Error()))
@ -386,7 +386,7 @@ func (h *handler) mkminer(w http.ResponseWriter, r *http.Request) {
Params: params,
}
signed, err := h.api.MpoolPushMessage(r.Context(), createStorageMinerMsg)
signed, err := h.api.MpoolPushMessage(r.Context(), createStorageMinerMsg, nil)
if err != nil {
w.WriteHeader(400)
w.Write([]byte(err.Error()))

View File

@ -19,15 +19,16 @@ import (
"golang.org/x/xerrors"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
"github.com/filecoin-project/specs-actors/actors/runtime/exitcode"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/tools/stats"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
"github.com/filecoin-project/specs-actors/actors/runtime/exitcode"
)
var log = logging.Logger("main")
@ -204,7 +205,7 @@ type processTipSetApi interface {
ChainGetParentReceipts(ctx context.Context, blockCid cid.Cid) ([]*types.MessageReceipt, error)
StateMinerInitialPledgeCollateral(ctx context.Context, addr address.Address, precommitInfo miner.SectorPreCommitInfo, tsk types.TipSetKey) (types.BigInt, error)
StateGetActor(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*types.Actor, error)
MpoolPushMessage(ctx context.Context, msg *types.Message) (*types.SignedMessage, error)
MpoolPushMessage(ctx context.Context, msg *types.Message, spec *api.MessageSendSpec) (*types.SignedMessage, error)
GasEstimateGasPremium(ctx context.Context, nblocksincl uint64, sender address.Address, gaslimit int64, tsk types.TipSetKey) (types.BigInt, error)
WalletBalance(ctx context.Context, addr address.Address) (types.BigInt, error)
}
@ -326,7 +327,7 @@ func ProcessTipset(ctx context.Context, api processTipSetApi, tipset *types.TipS
failures := 0
refundSum.SetUint64(0)
for _, msg := range messages {
if _, err = api.MpoolPushMessage(ctx, msg); err != nil {
if _, err = api.MpoolPushMessage(ctx, msg, nil); err != nil {
log.Errorw("failed to MpoolPushMessage", "err", err, "msg", msg)
failures = failures + 1
continue

View File

@ -3,19 +3,19 @@ package main
import (
"fmt"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/build"
"github.com/urfave/cli/v2"
"golang.org/x/xerrors"
"github.com/filecoin-project/lotus/chain/types"
lcli "github.com/filecoin-project/lotus/cli"
"github.com/filecoin-project/lotus/api/apibstore"
"github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
"github.com/filecoin-project/specs-actors/actors/util/adt"
"github.com/filecoin-project/lotus/api/apibstore"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/types"
lcli "github.com/filecoin-project/lotus/cli"
cbor "github.com/ipfs/go-ipld-cbor"
)
@ -75,7 +75,7 @@ var verifRegAddVerifierCmd = &cli.Command{
Params: params,
}
smsg, err := api.MpoolPushMessage(ctx, msg)
smsg, err := api.MpoolPushMessage(ctx, msg, nil)
if err != nil {
return err
}
@ -149,7 +149,7 @@ var verifRegVerifyClientCmd = &cli.Command{
Params: params,
}
smsg, err := api.MpoolPushMessage(ctx, msg)
smsg, err := api.MpoolPushMessage(ctx, msg, nil)
if err != nil {
return err
}

View File

@ -81,7 +81,7 @@ var actorSetAddrsCmd = &cli.Command{
GasLimit: gasLimit,
Method: 18,
Params: params,
})
}, nil)
if err != nil {
return err
}

View File

@ -560,7 +560,7 @@ func configureStorageMiner(ctx context.Context, api lapi.FullNode, addr address.
GasPremium: gasPrice,
}
smsg, err := api.MpoolPushMessage(ctx, msg)
smsg, err := api.MpoolPushMessage(ctx, msg, nil)
if err != nil {
return err
}
@ -640,7 +640,7 @@ func createStorageMiner(ctx context.Context, api lapi.FullNode, peerid peer.ID,
GasPremium: gasPrice,
}
signed, err := api.MpoolPushMessage(ctx, createStorageMinerMsg)
signed, err := api.MpoolPushMessage(ctx, createStorageMinerMsg, nil)
if err != nil {
return address.Undef, err
}

View File

@ -5,11 +5,12 @@ import (
"github.com/urfave/cli/v2"
"github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
"github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/types"
lcli "github.com/filecoin-project/lotus/cli"
"github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
)
var rewardsCmd = &cli.Command{
@ -65,7 +66,7 @@ var rewardsRedeemCmd = &cli.Command{
Value: types.NewInt(0),
Method: builtin.MethodsMiner.WithdrawBalance,
Params: params,
})
}, nil)
if err != nil {
return err
}

View File

@ -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)
ChainGetRandomnessFromBeacon(ctx context.Context, tok TipSetToken, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) (abi.Randomness, error)
ChainGetRandomnessFromTickets(ctx context.Context, tok TipSetToken, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) (abi.Randomness, error)
@ -54,6 +54,7 @@ type SealingAPI interface {
type Sealing struct {
api SealingAPI
feeCfg FeeConfig
events Events
maddr address.Address
@ -72,6 +73,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
@ -84,9 +90,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,

View File

@ -191,7 +191,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)})
}
@ -340,7 +340,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)})
}

View File

@ -6,8 +6,6 @@ import (
"bytes"
"context"
"github.com/filecoin-project/lotus/chain/events/state"
"golang.org/x/xerrors"
"github.com/filecoin-project/go-address"
@ -16,6 +14,7 @@ import (
"github.com/filecoin-project/go-fil-markets/storagemarket"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/events"
"github.com/filecoin-project/lotus/chain/events/state"
"github.com/filecoin-project/lotus/chain/market"
"github.com/filecoin-project/lotus/chain/stmgr"
"github.com/filecoin-project/lotus/chain/store"
@ -127,7 +126,7 @@ func (c *ClientNodeAdapter) AddFunds(ctx context.Context, addr address.Address,
From: addr,
Value: amount,
Method: builtin.MethodsMarket.AddBalance,
})
}, nil)
if err != nil {
return cid.Undef, err
}

View File

@ -79,7 +79,7 @@ func (n *ProviderNodeAdapter) PublishDeals(ctx context.Context, deal storagemark
Value: types.NewInt(0),
Method: builtin.MethodsMarket.PublishStorageDeals,
Params: params,
})
}, nil)
if err != nil {
return cid.Undef, err
}
@ -177,7 +177,7 @@ func (n *ProviderNodeAdapter) AddFunds(ctx context.Context, addr address.Address
From: addr,
Value: amount,
Method: builtin.MethodsMarket.AddBalance,
})
}, nil)
if err != nil {
return cid.Undef, err
}

View File

@ -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)),
)
}

View File

@ -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"

54
node/config/def_test.go Normal file
View File

@ -0,0 +1,54 @@
package config
import (
"bytes"
"fmt"
"reflect"
"strings"
"testing"
"github.com/BurntSushi/toml"
"github.com/stretchr/testify/require"
)
func TestDefaultFullNodeRoundtrip(t *testing.T) {
c := DefaultFullNode()
var s string
{
buf := new(bytes.Buffer)
_, _ = buf.WriteString("# Default config:\n")
e := toml.NewEncoder(buf)
require.NoError(t, e.Encode(c))
s = buf.String()
}
c2, err := FromReader(strings.NewReader(s), DefaultFullNode())
require.NoError(t, err)
fmt.Println(s)
require.True(t, reflect.DeepEqual(c, c2))
}
func TestDefaultMinerRoundtrip(t *testing.T) {
c := DefaultStorageMiner()
var s string
{
buf := new(bytes.Buffer)
_, _ = buf.WriteString("# Default config:\n")
e := toml.NewEncoder(buf)
require.NoError(t, e.Encode(c))
s = buf.String()
}
c2, err := FromReader(strings.NewReader(s), DefaultStorageMiner())
require.NoError(t, err)
fmt.Println(s)
require.True(t, reflect.DeepEqual(c, c2))
}

View File

@ -53,5 +53,4 @@ func ConfigComment(t interface{}) ([]byte, error) {
b = bytes.ReplaceAll(b, []byte("\n"), []byte("\n#"))
b = bytes.ReplaceAll(b, []byte("#["), []byte("["))
return b, nil
}

View File

@ -2,6 +2,8 @@ package full
import (
"context"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/abi/big"
"github.com/ipfs/go-cid"
"go.uber.org/fx"
@ -13,7 +15,6 @@ import (
"github.com/filecoin-project/lotus/chain/store"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/node/modules/dtypes"
"github.com/filecoin-project/specs-actors/actors/abi/big"
)
type MpoolAPI struct {
@ -108,7 +109,28 @@ func (a *MpoolAPI) MpoolPush(ctx context.Context, smsg *types.SignedMessage) (ci
return a.Mpool.Push(smsg)
}
func (a *MpoolAPI) MpoolPushMessage(ctx context.Context, msg *types.Message) (*types.SignedMessage, error) {
func capGasFee(msg *types.Message, maxFee abi.TokenAmount) {
if maxFee.Equals(big.Zero()) {
return
}
gl := types.BigMul(msg.GasPremium, types.NewInt(uint64(msg.GasLimit)))
totalFee := types.BigMul(msg.GasFeeCap, gl)
minerFee := types.BigMul(msg.GasPremium, gl)
if totalFee.LessThanEqual(maxFee) {
return
}
// scale chain/miner fee down proportionally to fit in our budget
// TODO: there are probably smarter things we can do here to optimize
// message inclusion latency
msg.GasFeeCap = big.Div(maxFee, gl)
msg.GasPremium = big.Div(big.Div(big.Mul(minerFee, maxFee), totalFee), gl)
}
func (a *MpoolAPI) MpoolPushMessage(ctx context.Context, msg *types.Message, spec *api.MessageSendSpec) (*types.SignedMessage, error) {
{
fromA, err := a.Stmgr.ResolveToKeyAddress(ctx, msg.From, nil)
if err != nil {
@ -148,6 +170,8 @@ func (a *MpoolAPI) MpoolPushMessage(ctx context.Context, msg *types.Message) (*t
msg.GasFeeCap = big.Add(feeCap, msg.GasPremium)
}
capGasFee(msg, spec.Get().MaxFee)
sign := func(from address.Address, nonce uint64) (*types.SignedMessage, error) {
msg.Nonce = nonce
if msg.From.Protocol() == address.ID {

View File

@ -78,7 +78,7 @@ func (a *MsigAPI) MsigCreate(ctx context.Context, req uint64, addrs []address.Ad
}
// send the message out to the network
smsg, err := a.MpoolAPI.MpoolPushMessage(ctx, &msg)
smsg, err := a.MpoolAPI.MpoolPushMessage(ctx, &msg, nil)
if err != nil {
return cid.Undef, err
}
@ -122,7 +122,7 @@ func (a *MsigAPI) MsigPropose(ctx context.Context, msig address.Address, to addr
Params: enc,
}
smsg, err := a.MpoolAPI.MpoolPushMessage(ctx, msg)
smsg, err := a.MpoolAPI.MpoolPushMessage(ctx, msg, nil)
if err != nil {
return cid.Undef, xerrors.Errorf("failed to push message: %w", err)
}
@ -236,7 +236,7 @@ func (a *MsigAPI) msigApproveOrCancel(ctx context.Context, operation api.MsigPro
Params: enc,
}
smsg, err := a.MpoolAPI.MpoolPushMessage(ctx, msg)
smsg, err := a.MpoolAPI.MpoolPushMessage(ctx, msg, nil)
if err != nil {
return cid.Undef, err
}

View File

@ -4,13 +4,14 @@ import (
"context"
"fmt"
"github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/filecoin-project/specs-actors/actors/builtin/paych"
"github.com/ipfs/go-cid"
"go.uber.org/fx"
"golang.org/x/xerrors"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/filecoin-project/specs-actors/actors/builtin/paych"
"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/types"
@ -209,7 +210,7 @@ func (a *PaychAPI) PaychVoucherSubmit(ctx context.Context, ch address.Address, s
Params: enc,
}
smsg, err := a.MpoolPushMessage(ctx, msg)
smsg, err := a.MpoolPushMessage(ctx, msg, nil)
if err != nil {
return cid.Undef, err
}

View File

@ -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) {

View File

@ -110,7 +110,7 @@ func testStorageNode(ctx context.Context, t *testing.T, waddr address.Address, a
Value: types.NewInt(0),
}
_, err = tnd.MpoolPushMessage(ctx, msg)
_, err = tnd.MpoolPushMessage(ctx, msg, nil)
require.NoError(t, err)
// start node

View File

@ -44,7 +44,7 @@ type stateManagerAPI interface {
// paychAPI defines the API methods needed by the payment channel manager
type paychAPI interface {
StateWaitMsg(ctx context.Context, msg cid.Cid, confidence uint64) (*api.MsgLookup, error)
MpoolPushMessage(ctx context.Context, msg *types.Message) (*types.SignedMessage, error)
MpoolPushMessage(ctx context.Context, msg *types.Message, maxFee *api.MessageSendSpec) (*types.SignedMessage, error)
}
// managerAPI defines all methods needed by the manager

View File

@ -156,7 +156,7 @@ func (pchapi *mockPaychAPI) close() {
}
}
func (pchapi *mockPaychAPI) MpoolPushMessage(ctx context.Context, msg *types.Message) (*types.SignedMessage, error) {
func (pchapi *mockPaychAPI) MpoolPushMessage(ctx context.Context, msg *types.Message, spec *api.MessageSendSpec) (*types.SignedMessage, error) {
pchapi.lk.Lock()
defer pchapi.lk.Unlock()

View File

@ -403,7 +403,7 @@ func (ca *channelAccessor) settle(ctx context.Context, ch address.Address) (cid.
Value: types.NewInt(0),
Method: builtin.MethodsPaych.Settle,
}
smgs, err := ca.api.MpoolPushMessage(ctx, msg)
smgs, err := ca.api.MpoolPushMessage(ctx, msg, nil)
if err != nil {
return cid.Undef, err
}
@ -433,7 +433,7 @@ func (ca *channelAccessor) collect(ctx context.Context, ch address.Address) (cid
Method: builtin.MethodsPaych.Collect,
}
smsg, err := ca.api.MpoolPushMessage(ctx, msg)
smsg, err := ca.api.MpoolPushMessage(ctx, msg, nil)
if err != nil {
return cid.Undef, err
}

View File

@ -370,7 +370,7 @@ func (ca *channelAccessor) createPaych(ctx context.Context, from, to address.Add
Params: enc,
}
smsg, err := ca.api.MpoolPushMessage(ctx, msg)
smsg, err := ca.api.MpoolPushMessage(ctx, msg, nil)
if err != nil {
return cid.Undef, xerrors.Errorf("initializing paych actor: %w", err)
}
@ -449,7 +449,7 @@ func (ca *channelAccessor) addFunds(ctx context.Context, channelInfo *ChannelInf
Method: 0,
}
smsg, err := ca.api.MpoolPushMessage(ctx, msg)
smsg, err := ca.api.MpoolPushMessage(ctx, msg, nil)
if err != nil {
return nil, err
}

View File

@ -3,6 +3,7 @@ package storage
import (
"bytes"
"context"
"github.com/filecoin-project/lotus/api"
"github.com/ipfs/go-cid"
cbg "github.com/whyrusleeping/cbor-gen"
@ -237,19 +238,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)
smsg, err := s.delegate.MpoolPushMessage(ctx, &msg, &api.MessageSendSpec{MaxFee: maxFee})
if err != nil {
return cid.Undef, err
}

View File

@ -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
@ -65,7 +67,7 @@ type storageMinerApi interface {
StateMinerFaults(context.Context, address.Address, types.TipSetKey) (abi.BitField, error)
StateMinerRecoveries(context.Context, address.Address, types.TipSetKey) (abi.BitField, error)
MpoolPushMessage(context.Context, *types.Message) (*types.SignedMessage, error)
MpoolPushMessage(context.Context, *types.Message, *api.MessageSendSpec) (*types.SignedMessage, error)
ChainHead(context.Context) (*types.TipSet, error)
ChainNotify(context.Context) (<-chan []*api.HeadChange, error)
@ -82,9 +84,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,
@ -109,10 +112,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

View File

@ -4,6 +4,7 @@ import (
"bytes"
"context"
"errors"
"github.com/filecoin-project/lotus/api"
"time"
"github.com/filecoin-project/go-bitfield"
@ -177,7 +178,7 @@ func (s *WindowPoStScheduler) checkNextRecoveries(ctx context.Context, dlIdx uin
Value: types.NewInt(0),
}
sm, err := s.api.MpoolPushMessage(ctx, msg)
sm, err := s.api.MpoolPushMessage(ctx, msg, &api.MessageSendSpec{MaxFee: abi.TokenAmount(s.feeCfg.MaxWindowPoStGasFee)})
if err != nil {
return xerrors.Errorf("pushing message to mpool: %w", err)
}
@ -259,7 +260,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)
sm, err := s.api.MpoolPushMessage(ctx, msg, &api.MessageSendSpec{MaxFee: abi.TokenAmount(s.feeCfg.MaxWindowPoStGasFee)})
if err != nil {
return xerrors.Errorf("pushing message to mpool: %w", err)
}
@ -465,7 +466,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)
sm, err := s.api.MpoolPushMessage(ctx, msg, &api.MessageSendSpec{MaxFee: abi.TokenAmount(s.feeCfg.MaxWindowPoStGasFee)})
if err != nil {
return xerrors.Errorf("pushing message to mpool: %w", err)
}

View File

@ -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,