Skip to content

Commit

Permalink
Merge pull request #5870 from filecoin-project/chore/pick-5832
Browse files Browse the repository at this point in the history
chore: cherry pick #5832
  • Loading branch information
diwufeiwen authored Mar 29, 2023
2 parents d2ebbb6 + df25073 commit 681aedf
Show file tree
Hide file tree
Showing 14 changed files with 170 additions and 57 deletions.
68 changes: 39 additions & 29 deletions app/submodule/eth/eth_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ import (

var log = logging.Logger("eth_api")

var ErrNullRound = errors.New("requested epoch was a null round")

func newEthAPI(em *EthSubModule) (*ethAPI, error) {
a := &ethAPI{
em: em,
Expand Down Expand Up @@ -184,7 +186,7 @@ func (a *ethAPI) EthGetBlockByHash(ctx context.Context, blkHash types.EthHash, f
return newEthBlockFromFilecoinTipSet(ctx, ts, fullTxInfo, a.em.chainModule.MessageStore, a.chain)
}

func (a *ethAPI) parseBlkParam(ctx context.Context, blkParam string) (tipset *types.TipSet, err error) {
func (a *ethAPI) parseBlkParam(ctx context.Context, blkParam string, strict bool) (tipset *types.TipSet, err error) {
if blkParam == "earliest" {
return nil, fmt.Errorf("block param \"earliest\" is not supported")
}
Expand All @@ -208,16 +210,22 @@ func (a *ethAPI) parseBlkParam(ctx context.Context, blkParam string) (tipset *ty
if err != nil {
return nil, fmt.Errorf("cannot parse block number: %v", err)
}
ts, err := a.em.chainModule.ChainReader.GetTipSetByHeight(ctx, nil, abi.ChainEpoch(num), false)
if abi.ChainEpoch(num) > head.Height()-1 {
return nil, fmt.Errorf("requested a future epoch (beyond 'latest')")
}
ts, err := a.chain.ChainGetTipSetByHeight(ctx, abi.ChainEpoch(num), head.Key())
if err != nil {
return nil, fmt.Errorf("cannot get tipset at height: %v", num)
}
if strict && ts.Height() != abi.ChainEpoch(num) {
return nil, ErrNullRound
}
return ts, nil
}
}

func (a *ethAPI) EthGetBlockByNumber(ctx context.Context, blkParam string, fullTxInfo bool) (types.EthBlock, error) {
ts, err := a.parseBlkParam(ctx, blkParam)
ts, err := a.parseBlkParam(ctx, blkParam, true)
if err != nil {
return types.EthBlock{}, err
}
Expand Down Expand Up @@ -322,7 +330,7 @@ func (a *ethAPI) EthGetTransactionCount(ctx context.Context, sender types.EthAdd
if err != nil {
return types.EthUint64(0), err
}
ts, err := a.parseBlkParam(ctx, blkParam)
ts, err := a.parseBlkParam(ctx, blkParam, false)
if err != nil {
return types.EthUint64(0), fmt.Errorf("cannot parse block param: %s", blkParam)
}
Expand Down Expand Up @@ -411,7 +419,7 @@ func (a *ethAPI) EthGetCode(ctx context.Context, ethAddr types.EthAddress, blkPa
return nil, fmt.Errorf("cannot get Filecoin address: %w", err)
}

ts, err := a.parseBlkParam(ctx, blkParam)
ts, err := a.parseBlkParam(ctx, blkParam, false)
if err != nil {
return nil, fmt.Errorf("cannot parse block param: %s", blkParam)
}
Expand Down Expand Up @@ -490,7 +498,7 @@ func (a *ethAPI) EthGetCode(ctx context.Context, ethAddr types.EthAddress, blkPa
}

func (a *ethAPI) EthGetStorageAt(ctx context.Context, ethAddr types.EthAddress, position types.EthBytes, blkParam string) (types.EthBytes, error) {
ts, err := a.parseBlkParam(ctx, blkParam)
ts, err := a.parseBlkParam(ctx, blkParam, false)
if err != nil {
return nil, fmt.Errorf("cannot parse block param: %s", blkParam)
}
Expand Down Expand Up @@ -586,7 +594,7 @@ func (a *ethAPI) EthGetBalance(ctx context.Context, address types.EthAddress, bl
return types.EthBigInt{}, err
}

ts, err := a.parseBlkParam(ctx, blkParam)
ts, err := a.parseBlkParam(ctx, blkParam, false)
if err != nil {
return types.EthBigInt{}, fmt.Errorf("cannot parse block param: %s", blkParam)
}
Expand Down Expand Up @@ -633,16 +641,12 @@ func (a *ethAPI) EthFeeHistory(ctx context.Context, p jsonrpc.RawParams) (types.
}
}

ts, err := a.parseBlkParam(ctx, params.NewestBlkNum)
ts, err := a.parseBlkParam(ctx, params.NewestBlkNum, false)
if err != nil {
return types.EthFeeHistory{}, fmt.Errorf("bad block parameter %s: %s", params.NewestBlkNum, err)
}

// Deal with the case that the chain is shorter than the number of requested blocks.
oldestBlkHeight := uint64(1)
if abi.ChainEpoch(params.BlkCount) <= ts.Height() {
oldestBlkHeight = uint64(ts.Height()) - uint64(params.BlkCount) + 1
}

// NOTE: baseFeePerGas should include the next block after the newest of the returned range,
// because the next base fee can be inferred from the messages in the newest block.
Expand All @@ -652,29 +656,31 @@ func (a *ethAPI) EthFeeHistory(ctx context.Context, p jsonrpc.RawParams) (types.
gasUsedRatioArray := []float64{}
rewardsArray := make([][]types.EthBigInt, 0)

for ts.Height() >= abi.ChainEpoch(oldestBlkHeight) {
// Unfortunately we need to rebuild the full message view so we can
// totalize gas used in the tipset.
msgs, err := a.em.chainModule.MessageStore.MessagesForTipset(ts)
blocksIncluded := 0
for blocksIncluded < int(params.BlkCount) && ts.Height() > 0 {
compOutput, err := a.chain.StateCompute(ctx, ts.Height(), nil, ts.Key())
if err != nil {
return types.EthFeeHistory{}, fmt.Errorf("error loading messages for tipset: %v: %w", ts, err)
return types.EthFeeHistory{}, fmt.Errorf("cannot lookup the status of for tipset: %v: %w", ts, err)
}

txGasRewards := gasRewardSorter{}
for txIdx, msg := range msgs {
msgLookup, err := a.chain.StateSearchMsg(ctx, types.EmptyTSK, msg.Cid(), constants.LookbackNoLimit, false)
if err != nil || msgLookup == nil {
return types.EthFeeHistory{}, nil
for _, msg := range compOutput.Trace {
if msg.Msg.From == builtintypes.SystemActorAddr {
continue
}

tx, err := newEthTxFromMessageLookup(ctx, msgLookup, txIdx, a.em.chainModule.MessageStore, a.chain)
smsgCid, err := getSignedMessage(ctx, a.em.chainModule.MessageStore, msg.MsgCid)
if err != nil {
return types.EthFeeHistory{}, nil
return types.EthFeeHistory{}, fmt.Errorf("failed to get signed msg %s: %w", msg.MsgCid, err)
}
tx, err := newEthTxFromSignedMessage(ctx, smsgCid, a.chain)
if err != nil {
return types.EthFeeHistory{}, err
}

txGasRewards = append(txGasRewards, gasRewardTuple{
reward: tx.Reward(ts.Blocks()[0].ParentBaseFee),
gas: uint64(msgLookup.Receipt.GasUsed),
gas: uint64(msg.MsgRct.GasUsed),
})
}

Expand All @@ -684,6 +690,8 @@ func (a *ethAPI) EthFeeHistory(ctx context.Context, p jsonrpc.RawParams) (types.
baseFeeArray = append(baseFeeArray, types.EthBigInt(ts.Blocks()[0].ParentBaseFee))
gasUsedRatioArray = append(gasUsedRatioArray, float64(totalGasUsed)/float64(constants.BlockGasLimit))
rewardsArray = append(rewardsArray, rewards)
oldestBlkHeight = uint64(ts.Height())
blocksIncluded++

parentTSKey := ts.Parents()
ts, err = a.chain.ChainGetTipSet(ctx, parentTSKey)
Expand Down Expand Up @@ -1033,7 +1041,7 @@ func (a *ethAPI) EthCall(ctx context.Context, tx types.EthCall, blkParam string)
if err != nil {
return nil, fmt.Errorf("failed to convert ethcall to filecoin message: %w", err)
}
ts, err := a.parseBlkParam(ctx, blkParam)
ts, err := a.parseBlkParam(ctx, blkParam, false)
if err != nil {
return nil, fmt.Errorf("cannot parse block param: %s", blkParam)
}
Expand Down Expand Up @@ -1091,12 +1099,16 @@ func newEthBlockFromFilecoinTipSet(ctx context.Context, ts *types.TipSet, fullTx
return types.EthBlock{}, fmt.Errorf("failed to compute state: %w", err)
}

for txIdx, msg := range compOutput.Trace {
txIdx := 0
for _, msg := range compOutput.Trace {
// skip system messages like reward application and cron
if msg.Msg.From == builtintypes.SystemActorAddr {
continue
}

ti := types.EthUint64(txIdx)
txIdx++

gasUsed += msg.MsgRct.GasUsed
smsgCid, err := getSignedMessage(ctx, ms, msg.MsgCid)
if err != nil {
Expand All @@ -1107,8 +1119,6 @@ func newEthBlockFromFilecoinTipSet(ctx context.Context, ts *types.TipSet, fullTx
return types.EthBlock{}, fmt.Errorf("failed to convert msg to ethTx: %w", err)
}

ti := types.EthUint64(txIdx)

tx.ChainID = types.EthUint64(types2.Eip155ChainID)
tx.BlockHash = &blkHash
tx.BlockNumber = &bn
Expand Down Expand Up @@ -1643,7 +1653,7 @@ func calculateRewardsAndGasUsed(rewardPercentiles []float64, txGasRewards gasRew

rewards := make([]types.EthBigInt, len(rewardPercentiles))
for i := range rewards {
rewards[i] = types.EthBigIntZero
rewards[i] = types.EthBigInt(types.NewInt(messagepool.MinGasPremium))
}

if len(txGasRewards) == 0 {
Expand Down
3 changes: 2 additions & 1 deletion app/submodule/eth/eth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/stretchr/testify/require"

"github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/venus/pkg/messagepool"
"github.com/filecoin-project/venus/venus-shared/types"
)

Expand Down Expand Up @@ -133,7 +134,7 @@ func TestRewardPercentiles(t *testing.T) {
{
percentiles: []float64{25, 50, 75},
txGasRewards: []gasRewardTuple{},
answer: []int64{0, 0, 0},
answer: []int64{messagepool.MinGasPremium, messagepool.MinGasPremium, messagepool.MinGasPremium},
},
{
percentiles: []float64{25, 50, 75, 100},
Expand Down
17 changes: 12 additions & 5 deletions cmd/mpool.go
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,8 @@ var mpoolReplaceCmd = &cmds.Command{
cmds.StringOption("max-fee", "Spend up to X FIL for this message (applicable for auto mode)"),
},
Run: func(req *cmds.Request, re cmds.ResponseEmitter, env cmds.Environment) error {
ctx := requestContext(req)

feecap, premium, gasLimit, err := parseGasOptions(req)
if err != nil {
return err
Expand All @@ -243,7 +245,7 @@ var mpoolReplaceCmd = &cmds.Command{
return err
}

msg, err := env.(*node.Env).ChainAPI.ChainGetMessage(req.Context, mcid)
msg, err := env.(*node.Env).ChainAPI.ChainGetMessage(ctx, mcid)
if err != nil {
return fmt.Errorf("could not find referenced message: %w", err)
}
Expand All @@ -267,12 +269,12 @@ var mpoolReplaceCmd = &cmds.Command{
return errors.New("command syntax error")
}

ts, err := env.(*node.Env).ChainAPI.ChainHead(req.Context)
ts, err := env.(*node.Env).ChainAPI.ChainHead(ctx)
if err != nil {
return fmt.Errorf("getting chain head: %w", err)
}

pending, err := env.(*node.Env).MessagePoolAPI.MpoolPending(req.Context, ts.Key())
pending, err := env.(*node.Env).MessagePoolAPI.MpoolPending(ctx, ts.Key())
if err != nil {
return err
}
Expand All @@ -292,7 +294,12 @@ var mpoolReplaceCmd = &cmds.Command{
msg := found.Message

if auto {
minRBF := messagepool.ComputeMinRBF(msg.GasPremium)
cfg, err := getEnv(env).MessagePoolAPI.MpoolGetConfig(ctx)
if err != nil {
return fmt.Errorf("failed to lookup the message pool config: %w", err)
}

defaultRBF := messagepool.ComputeRBF(msg.GasPremium, cfg.ReplaceByFeeRatio)

var mss *types.MessageSendSpec
if len(maxFee) > 0 {
Expand All @@ -313,7 +320,7 @@ var mpoolReplaceCmd = &cmds.Command{
return fmt.Errorf("failed to estimate gas values: %w", err)
}

msg.GasPremium = big.Max(retm.GasPremium, minRBF)
msg.GasPremium = big.Max(retm.GasPremium, defaultRBF)
msg.GasFeeCap = big.Max(retm.GasFeeCap, msg.GasPremium)

mff := func() (abi.TokenAmount, error) {
Expand Down
13 changes: 13 additions & 0 deletions cmd/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -228,3 +228,16 @@ func isController(mi types.MinerInfo, addr address.Address) bool {
func getEnv(env cmds.Environment) *node.Env {
return env.(*node.Env)
}

func requestContext(req *cmds.Request) context.Context {
ctx, cancel := context.WithCancel(req.Context)

sig := make(chan os.Signal, 2)
go func() {
<-sig
cancel()
}()
signal.Notify(sig, syscall.SIGTERM, syscall.SIGINT, syscall.SIGHUP)

return ctx
}
17 changes: 11 additions & 6 deletions pkg/messagepool/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,15 @@ import (

"github.com/filecoin-project/go-address"
"github.com/filecoin-project/venus/pkg/repo"
"github.com/filecoin-project/venus/venus-shared/types"
)

var (
ReplaceByFeePercentageMinimum types.Percent = 110
ReplaceByFeePercentageDefault types.Percent = 125
)

var (
ReplaceByFeeRatioDefault = 1.25
MemPoolSizeLimitHiDefault = 30000
MemPoolSizeLimitLoDefault = 20000
PruneCooldownDefault = time.Minute
Expand All @@ -26,7 +31,7 @@ type MpoolConfig struct {
PriorityAddrs []address.Address
SizeLimitHigh int
SizeLimitLow int
ReplaceByFeeRatio float64
ReplaceByFeeRatio types.Percent
PruneCooldown time.Duration
GasLimitOverestimation float64
}
Expand Down Expand Up @@ -71,9 +76,9 @@ func (mp *MessagePool) GetConfig() *MpoolConfig {
}

func validateConfg(cfg *MpoolConfig) error {
if cfg.ReplaceByFeeRatio < ReplaceByFeeRatioDefault {
return fmt.Errorf("'ReplaceByFeeRatio' is less than required %f < %f",
cfg.ReplaceByFeeRatio, ReplaceByFeeRatioDefault)
if cfg.ReplaceByFeeRatio < ReplaceByFeePercentageMinimum {
return fmt.Errorf("'ReplaceByFeeRatio' is less than required %s < %s",
cfg.ReplaceByFeeRatio, ReplaceByFeePercentageMinimum)
}
if cfg.GasLimitOverestimation < 1 {
return fmt.Errorf("'GasLimitOverestimation' cannot be less than 1")
Expand Down Expand Up @@ -102,7 +107,7 @@ func DefaultConfig() *MpoolConfig {
return &MpoolConfig{
SizeLimitHigh: MemPoolSizeLimitHiDefault,
SizeLimitLow: MemPoolSizeLimitLoDefault,
ReplaceByFeeRatio: ReplaceByFeeRatioDefault,
ReplaceByFeeRatio: ReplaceByFeePercentageDefault,
PruneCooldown: PruneCooldownDefault,
GasLimitOverestimation: GasLimitOverestimation,
}
Expand Down
18 changes: 10 additions & 8 deletions pkg/messagepool/messagepool.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,8 @@ var log = logging.Logger("messagepool")

var futureDebug = false

var (
rbfNumBig = big.NewInt(int64((ReplaceByFeeRatioDefault - 1) * RbfDenom))
rbfDenomBig = big.NewInt(RbfDenom)
)

const RbfDenom = 256
var rbfNumBig = types.NewInt(uint64(ReplaceByFeePercentageMinimum))
var rbfDenomBig = types.NewInt(100)

var RepublishInterval time.Duration

Expand Down Expand Up @@ -208,8 +204,14 @@ func newMsgSet(nonce uint64) *msgSet {
}

func ComputeMinRBF(curPrem abi.TokenAmount) abi.TokenAmount {
minPrice := big.Add(curPrem, big.Div(big.Mul(curPrem, rbfNumBig), rbfDenomBig))
return big.Add(minPrice, big.NewInt(1))
minPrice := types.BigDiv(types.BigMul(curPrem, rbfNumBig), rbfDenomBig)
return types.BigAdd(minPrice, types.NewInt(1))
}

func ComputeRBF(curPrem abi.TokenAmount, replaceByFeeRatio types.Percent) abi.TokenAmount {
rbfNumBig := types.NewInt(uint64(replaceByFeeRatio))
minPrice := types.BigDiv(types.BigMul(curPrem, rbfNumBig), rbfDenomBig)
return types.BigAdd(minPrice, types.NewInt(1))
}

func CapGasFee(mff DefaultMaxFeeFunc, msg *types.Message, sendSepc *types.MessageSendSpec) {
Expand Down
4 changes: 4 additions & 0 deletions venus-devtool/api-gen/example.go
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,10 @@ func init() {
FromBlock: pstring("2301220"),
Address: []types.EthAddress{ethaddr},
})

percent := types.Percent(123)
addExample(percent)
addExample(&percent)
}

func ExampleValue(method string, t, parent reflect.Type) interface{} {
Expand Down
2 changes: 1 addition & 1 deletion venus-devtool/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ require (
github.com/filecoin-project/go-fil-markets v1.25.2
github.com/filecoin-project/go-jsonrpc v0.2.1
github.com/filecoin-project/go-state-types v0.10.0
github.com/filecoin-project/lotus v1.20.1
github.com/filecoin-project/lotus v1.20.3
github.com/filecoin-project/venus v0.0.0-00010101000000-000000000000
github.com/google/uuid v1.3.0
github.com/ipfs/go-cid v0.3.2
Expand Down
4 changes: 2 additions & 2 deletions venus-devtool/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -338,8 +338,8 @@ github.com/filecoin-project/go-statemachine v1.0.2 h1:421SSWBk8GIoCoWYYTE/d+qCWc
github.com/filecoin-project/go-statestore v0.2.0 h1:cRRO0aPLrxKQCZ2UOQbzFGn4WDNdofHZoGPjfNaAo5Q=
github.com/filecoin-project/go-statestore v0.2.0/go.mod h1:8sjBYbS35HwPzct7iT4lIXjLlYyPor80aU7t7a/Kspo=
github.com/filecoin-project/index-provider v0.9.1 h1:Jnh9dviIHvQxZ2baNoYu3n8z6F9O62ksnVlyREgPyyM=
github.com/filecoin-project/lotus v1.20.1 h1:thlefi6NROiJo58dRBf+RweNmTlxCFdEIysLjx83tMw=
github.com/filecoin-project/lotus v1.20.1/go.mod h1:dprpVaiQezI8Jl4tWcPNIYGGAAo31feZlGAOk8D7bJU=
github.com/filecoin-project/lotus v1.20.3 h1:7Szh7jCc8pOa1++tdZgaUGMJYSHIMkUpypAO4at9I2U=
github.com/filecoin-project/lotus v1.20.3/go.mod h1:eNjjbZvjLgH7OEaD7kAkk5i8OrZ7owq349yfQ1wrVTo=
github.com/filecoin-project/pubsub v1.0.0 h1:ZTmT27U07e54qV1mMiQo4HDr0buo8I1LDHBYLXlsNXM=
github.com/filecoin-project/pubsub v1.0.0/go.mod h1:GkpB33CcUtUNrLPhJgfdy4FDx4OMNR9k+46DHx/Lqrg=
github.com/filecoin-project/specs-actors v0.9.13/go.mod h1:TS1AW/7LbG+615j4NsjMK1qlpAwaFsG9w0V2tg2gSao=
Expand Down
Loading

0 comments on commit 681aedf

Please sign in to comment.