Merge pull request #3007 from filecoin-project/fix/rbf-gaspremoim

Validate message pool config, validate GasPremium < GasFeeCap
This commit is contained in:
Łukasz Magiera 2020-08-12 20:40:08 +02:00 committed by GitHub
commit fd41a16f84
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 30 additions and 14 deletions

View File

@ -2,6 +2,7 @@ package messagepool
import ( import (
"encoding/json" "encoding/json"
"fmt"
"time" "time"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
@ -35,10 +36,6 @@ func loadConfig(ds dtypes.MetadataDS) (*types.MpoolConfig, error) {
} }
cfg := new(types.MpoolConfig) cfg := new(types.MpoolConfig)
err = json.Unmarshal(cfgBytes, cfg) err = json.Unmarshal(cfgBytes, cfg)
if cfg.GasLimitOverestimation == 0 {
// TODO: remove in next reset
cfg.GasLimitOverestimation = GasLimitOverestimation
}
return cfg, err return cfg, err
} }
@ -56,16 +53,32 @@ func (mp *MessagePool) GetConfig() *types.MpoolConfig {
return mp.cfg.Clone() return mp.cfg.Clone()
} }
func (mp *MessagePool) SetConfig(cfg *types.MpoolConfig) { func validateConfg(cfg *types.MpoolConfig) error {
if cfg.ReplaceByFeeRatio < ReplaceByFeeRatioDefault {
return fmt.Errorf("'ReplaceByFeeRatio' is less than required %f < %f",
cfg.ReplaceByFeeRatio, ReplaceByFeeRatioDefault)
}
if cfg.GasLimitOverestimation < 1 {
return fmt.Errorf("'GasLimitOverestimation' cannot be less than 1")
}
return nil
}
func (mp *MessagePool) SetConfig(cfg *types.MpoolConfig) error {
if err := validateConfg(cfg); err != nil {
return err
}
cfg = cfg.Clone() cfg = cfg.Clone()
mp.cfgLk.Lock() mp.cfgLk.Lock()
mp.cfg = cfg mp.cfg = cfg
mp.rbfNum = types.NewInt(uint64((cfg.ReplaceByFeeRatio - 1) * RbfDenom))
err := saveConfig(cfg, mp.ds) err := saveConfig(cfg, mp.ds)
if err != nil { if err != nil {
log.Warnf("error persisting mpool config: %s", err) log.Warnf("error persisting mpool config: %s", err)
} }
mp.cfgLk.Unlock() mp.cfgLk.Unlock()
return nil
} }
func DefaultConfig() *types.MpoolConfig { func DefaultConfig() *types.MpoolConfig {

View File

@ -38,6 +38,9 @@ var log = logging.Logger("messagepool")
const futureDebug = false const futureDebug = false
var rbfNumBig = types.NewInt(uint64((ReplaceByFeeRatioDefault - 1) * RbfDenom))
var rbfDenomBig = types.NewInt(RbfDenom)
const RbfDenom = 256 const RbfDenom = 256
var RepublishInterval = pubsub.TimeCacheDuration + time.Duration(5*build.BlockDelaySecs+build.PropagationDelaySecs)*time.Second var RepublishInterval = pubsub.TimeCacheDuration + time.Duration(5*build.BlockDelaySecs+build.PropagationDelaySecs)*time.Second
@ -81,8 +84,6 @@ type MessagePool struct {
cfgLk sync.Mutex cfgLk sync.Mutex
cfg *types.MpoolConfig cfg *types.MpoolConfig
rbfNum, rbfDenom types.BigInt
api Provider api Provider
minGasPrice types.BigInt minGasPrice types.BigInt
@ -126,7 +127,7 @@ func (ms *msgSet) add(m *types.SignedMessage, mp *MessagePool) (bool, error) {
if m.Cid() != exms.Cid() { if m.Cid() != exms.Cid() {
// check if RBF passes // check if RBF passes
minPrice := exms.Message.GasPremium minPrice := exms.Message.GasPremium
minPrice = types.BigAdd(minPrice, types.BigDiv(types.BigMul(minPrice, mp.rbfNum), mp.rbfDenom)) minPrice = types.BigAdd(minPrice, types.BigDiv(types.BigMul(minPrice, rbfNumBig), rbfDenomBig))
minPrice = types.BigAdd(minPrice, types.NewInt(1)) minPrice = types.BigAdd(minPrice, types.NewInt(1))
if types.BigCmp(m.Message.GasPremium, minPrice) >= 0 { if types.BigCmp(m.Message.GasPremium, minPrice) >= 0 {
log.Infow("add with RBF", "oldpremium", exms.Message.GasPremium, log.Infow("add with RBF", "oldpremium", exms.Message.GasPremium,
@ -172,8 +173,6 @@ func New(api Provider, ds dtypes.MetadataDS, netName dtypes.NetworkName) (*Messa
api: api, api: api,
netName: netName, netName: netName,
cfg: cfg, cfg: cfg,
rbfNum: types.NewInt(uint64((cfg.ReplaceByFeeRatio - 1) * RbfDenom)),
rbfDenom: types.NewInt(RbfDenom),
} }
// enable initial prunes // enable initial prunes

View File

@ -170,6 +170,10 @@ func (m *Message) ValidForBlockInclusion(minGas int64) error {
return xerrors.New("'GasPremium' field cannot be negative") return xerrors.New("'GasPremium' field cannot be negative")
} }
if m.GasPremium.GreaterThan(m.GasFeeCap) {
return xerrors.New("'GasFeeCap' less than 'GasPremium'")
}
if m.GasLimit > build.BlockGasLimit { if m.GasLimit > build.BlockGasLimit {
return xerrors.New("'GasLimit' field cannot be greater than a block's gas limit") return xerrors.New("'GasLimit' field cannot be greater than a block's gas limit")
} }

View File

@ -13,6 +13,7 @@ import (
"github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/store"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/node/modules/dtypes" "github.com/filecoin-project/lotus/node/modules/dtypes"
"github.com/filecoin-project/specs-actors/actors/abi/big"
) )
type MpoolAPI struct { type MpoolAPI struct {
@ -33,8 +34,7 @@ func (a *MpoolAPI) MpoolGetConfig(context.Context) (*types.MpoolConfig, error) {
} }
func (a *MpoolAPI) MpoolSetConfig(ctx context.Context, cfg *types.MpoolConfig) error { func (a *MpoolAPI) MpoolSetConfig(ctx context.Context, cfg *types.MpoolConfig) error {
a.Mpool.SetConfig(cfg) return a.Mpool.SetConfig(cfg)
return nil
} }
func (a *MpoolAPI) MpoolSelect(ctx context.Context, tsk types.TipSetKey, ticketQuality float64) ([]*types.SignedMessage, error) { func (a *MpoolAPI) MpoolSelect(ctx context.Context, tsk types.TipSetKey, ticketQuality float64) ([]*types.SignedMessage, error) {
@ -145,7 +145,7 @@ func (a *MpoolAPI) MpoolPushMessage(ctx context.Context, msg *types.Message) (*t
if err != nil { if err != nil {
return nil, xerrors.Errorf("estimating fee cap: %w", err) return nil, xerrors.Errorf("estimating fee cap: %w", err)
} }
msg.GasFeeCap = feeCap msg.GasFeeCap = big.Add(feeCap, msg.GasPremium)
} }
return a.Mpool.PushWithNonce(ctx, msg.From, func(from address.Address, nonce uint64) (*types.SignedMessage, error) { return a.Mpool.PushWithNonce(ctx, msg.From, func(from address.Address, nonce uint64) (*types.SignedMessage, error) {