@@ -0,0 +1,55 @@
|
||||
package full
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"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/specs-actors/actors/runtime/exitcode"
|
||||
"go.uber.org/fx"
|
||||
"golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
type GasAPI struct {
|
||||
fx.In
|
||||
Stmgr *stmgr.StateManager
|
||||
Cs *store.ChainStore
|
||||
}
|
||||
|
||||
const MinGasPrice = 1
|
||||
|
||||
func (a *GasAPI) GasEstimateGasPrice(ctx context.Context, nblocksincl uint64,
|
||||
sender address.Address, gaslimit int64, tsk types.TipSetKey) (types.BigInt, error) {
|
||||
|
||||
// TODO: something smarter obviously
|
||||
switch nblocksincl {
|
||||
case 0:
|
||||
return types.NewInt(MinGasPrice + 2), nil
|
||||
case 1:
|
||||
return types.NewInt(MinGasPrice + 1), nil
|
||||
default:
|
||||
return types.NewInt(MinGasPrice), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (a *GasAPI) GasEstimateGasLimit(ctx context.Context, msgIn *types.Message,
|
||||
tsk types.TipSetKey) (int64, error) {
|
||||
|
||||
msg := &(*msgIn)
|
||||
msg.GasLimit = build.BlockGasLimit
|
||||
|
||||
ts, err := a.Cs.GetTipSetFromKey(tsk)
|
||||
if err != nil {
|
||||
return -1, xerrors.Errorf("could not get tipset: %w", err)
|
||||
}
|
||||
|
||||
res, err := a.Stmgr.CallWithGas(ctx, msg, ts)
|
||||
if res.MsgRct.ExitCode != exitcode.Ok {
|
||||
return -1, xerrors.Errorf("could not apply message: exit %s, reason: %s", res.MsgRct.ExitCode, res.Error)
|
||||
}
|
||||
|
||||
return res.MsgRct.GasUsed, nil
|
||||
}
|
||||
+14
-6
@@ -18,6 +18,7 @@ type MpoolAPI struct {
|
||||
fx.In
|
||||
|
||||
WalletAPI
|
||||
GasAPI
|
||||
|
||||
Chain *store.ChainStore
|
||||
|
||||
@@ -86,15 +87,26 @@ func (a *MpoolAPI) MpoolPush(ctx context.Context, smsg *types.SignedMessage) (ci
|
||||
return a.Mpool.Push(smsg)
|
||||
}
|
||||
|
||||
// GasMargin sets by how much should gas limit be increased over test execution
|
||||
var GasMargin = 1.2
|
||||
|
||||
func (a *MpoolAPI) MpoolPushMessage(ctx context.Context, msg *types.Message) (*types.SignedMessage, error) {
|
||||
if msg.Nonce != 0 {
|
||||
return nil, xerrors.Errorf("MpoolPushMessage expects message nonce to be 0, was %d", msg.Nonce)
|
||||
}
|
||||
if msg.GasLimit == 0 {
|
||||
msg.GasLimit = 100_000_000 // TODO: gas limit estimation
|
||||
gasLimit, err := a.GasEstimateGasLimit(ctx, msg, types.TipSetKey{})
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("estimating gas limit: %w", err)
|
||||
}
|
||||
msg.GasLimit = int64(float64(gasLimit) * GasMargin)
|
||||
}
|
||||
if types.BigCmp(msg.GasPrice, types.NewInt(0)) == 0 {
|
||||
msg.GasPrice = types.NewInt(1) // TODO: gas price estimation
|
||||
gasPrice, err := a.GasEstimateGasPrice(ctx, 2, msg.From, msg.GasLimit, types.TipSetKey{})
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("estimating gas price: %w", err)
|
||||
}
|
||||
msg.GasPrice = gasPrice
|
||||
}
|
||||
|
||||
return a.Mpool.PushWithNonce(ctx, msg.From, func(from address.Address, nonce uint64) (*types.SignedMessage, error) {
|
||||
@@ -124,7 +136,3 @@ func (a *MpoolAPI) MpoolGetNonce(ctx context.Context, addr address.Address) (uin
|
||||
func (a *MpoolAPI) MpoolSub(ctx context.Context) (<-chan api.MpoolUpdate, error) {
|
||||
return a.Mpool.Updates(ctx)
|
||||
}
|
||||
|
||||
func (a *MpoolAPI) MpoolEstimateGasPrice(ctx context.Context, nblocksincl uint64, sender address.Address, gaslimit int64, tsk types.TipSetKey) (types.BigInt, error) {
|
||||
return a.Mpool.EstimateGasPrice(ctx, nblocksincl, sender, gaslimit, tsk)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user