mirror of
https://github.com/filecoin-project/lotus.git
synced 2025-08-24 17:31:42 +08:00
142 lines
4.0 KiB
Go
142 lines
4.0 KiB
Go
package full
|
|
|
|
import (
|
|
"context"
|
|
|
|
"go.uber.org/fx"
|
|
"golang.org/x/xerrors"
|
|
|
|
"github.com/filecoin-project/go-address"
|
|
|
|
"github.com/filecoin-project/lotus/api"
|
|
"github.com/filecoin-project/lotus/build/buildconstants"
|
|
"github.com/filecoin-project/lotus/chain/messagepool"
|
|
"github.com/filecoin-project/lotus/chain/stmgr"
|
|
"github.com/filecoin-project/lotus/chain/store"
|
|
"github.com/filecoin-project/lotus/chain/types"
|
|
"github.com/filecoin-project/lotus/node/impl/gasutils"
|
|
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
|
)
|
|
|
|
type GasModuleAPI interface {
|
|
GasEstimateMessageGas(ctx context.Context, msg *types.Message, spec *api.MessageSendSpec, tsk types.TipSetKey) (*types.Message, error)
|
|
}
|
|
|
|
var _ GasModuleAPI = *new(api.FullNode)
|
|
|
|
// GasModule provides a default implementation of GasModuleAPI.
|
|
// It can be swapped out with another implementation through Dependency
|
|
// Injection (for example with a thin RPC client).
|
|
type GasModule struct {
|
|
fx.In
|
|
Stmgr *stmgr.StateManager
|
|
Chain *store.ChainStore
|
|
Mpool *messagepool.MessagePool
|
|
GetMaxFee dtypes.DefaultMaxFeeFunc
|
|
|
|
PriceCache *gasutils.GasPriceCache
|
|
}
|
|
|
|
var _ GasModuleAPI = (*GasModule)(nil)
|
|
|
|
type GasAPI struct {
|
|
fx.In
|
|
|
|
GasModuleAPI
|
|
|
|
Stmgr *stmgr.StateManager
|
|
Chain *store.ChainStore
|
|
Mpool *messagepool.MessagePool
|
|
|
|
PriceCache *gasutils.GasPriceCache
|
|
}
|
|
|
|
func (a *GasAPI) GasEstimateFeeCap(
|
|
ctx context.Context,
|
|
msg *types.Message,
|
|
maxqueueblks int64,
|
|
tsk types.TipSetKey,
|
|
) (types.BigInt, error) {
|
|
return gasutils.GasEstimateFeeCap(a.Chain, msg, maxqueueblks)
|
|
}
|
|
|
|
func (m *GasModule) GasEstimateFeeCap(
|
|
ctx context.Context,
|
|
msg *types.Message,
|
|
maxqueueblks int64,
|
|
tsk types.TipSetKey,
|
|
) (types.BigInt, error) {
|
|
return gasutils.GasEstimateFeeCap(m.Chain, msg, maxqueueblks)
|
|
}
|
|
|
|
func (a *GasAPI) GasEstimateGasPremium(
|
|
ctx context.Context,
|
|
nblocksincl uint64,
|
|
sender address.Address,
|
|
gaslimit int64,
|
|
_ types.TipSetKey,
|
|
) (types.BigInt, error) {
|
|
return gasutils.GasEstimateGasPremium(ctx, a.Chain, a.PriceCache, nblocksincl)
|
|
}
|
|
|
|
func (m *GasModule) GasEstimateGasPremium(
|
|
ctx context.Context,
|
|
nblocksincl uint64,
|
|
sender address.Address,
|
|
gaslimit int64,
|
|
_ types.TipSetKey,
|
|
) (types.BigInt, error) {
|
|
return gasutils.GasEstimateGasPremium(ctx, m.Chain, m.PriceCache, nblocksincl)
|
|
}
|
|
|
|
func (a *GasAPI) GasEstimateGasLimit(ctx context.Context, msgIn *types.Message, tsk types.TipSetKey) (int64, error) {
|
|
ts, err := a.Chain.GetTipSetFromKey(ctx, tsk)
|
|
if err != nil {
|
|
return -1, xerrors.Errorf("getting tipset: %w", err)
|
|
}
|
|
return gasutils.GasEstimateGasLimit(ctx, a.Chain, a.Stmgr, a.Mpool, msgIn, ts)
|
|
}
|
|
|
|
func (m *GasModule) GasEstimateGasLimit(ctx context.Context, msgIn *types.Message, tsk types.TipSetKey) (int64, error) {
|
|
ts, err := m.Chain.GetTipSetFromKey(ctx, tsk)
|
|
if err != nil {
|
|
return -1, xerrors.Errorf("getting tipset: %w", err)
|
|
}
|
|
return gasutils.GasEstimateGasLimit(ctx, m.Chain, m.Stmgr, m.Mpool, msgIn, ts)
|
|
}
|
|
|
|
func (m *GasModule) GasEstimateMessageGas(ctx context.Context, msg *types.Message, spec *api.MessageSendSpec, _ types.TipSetKey) (*types.Message, error) {
|
|
if msg.GasLimit == 0 {
|
|
gasLimit, err := m.GasEstimateGasLimit(ctx, msg, types.EmptyTSK)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
msg.GasLimit = int64(float64(gasLimit) * m.Mpool.GetConfig().GasLimitOverestimation)
|
|
|
|
// Gas overestimation can cause us to exceed the block gas limit, cap it.
|
|
if msg.GasLimit > buildconstants.BlockGasLimit {
|
|
msg.GasLimit = buildconstants.BlockGasLimit
|
|
}
|
|
}
|
|
|
|
if msg.GasPremium == types.EmptyInt || types.BigCmp(msg.GasPremium, types.NewInt(0)) == 0 {
|
|
gasPremium, err := m.GasEstimateGasPremium(ctx, 10, msg.From, msg.GasLimit, types.EmptyTSK)
|
|
if err != nil {
|
|
return nil, xerrors.Errorf("estimating gas price: %w", err)
|
|
}
|
|
msg.GasPremium = gasPremium
|
|
}
|
|
|
|
if msg.GasFeeCap == types.EmptyInt || types.BigCmp(msg.GasFeeCap, types.NewInt(0)) == 0 {
|
|
feeCap, err := m.GasEstimateFeeCap(ctx, msg, 20, types.EmptyTSK)
|
|
if err != nil {
|
|
return nil, xerrors.Errorf("estimating fee cap: %w", err)
|
|
}
|
|
msg.GasFeeCap = feeCap
|
|
}
|
|
|
|
messagepool.CapGasFee(m.GetMaxFee, msg, spec)
|
|
|
|
return msg, nil
|
|
}
|