diff --git a/app/config/config.go b/app/config/config.go index e2e48404ad..838c97bfd3 100644 --- a/app/config/config.go +++ b/app/config/config.go @@ -122,6 +122,8 @@ type OecConfig struct { // commitGapOffset int64 + // enable mempool sim gu factor + enableMempoolSimGuFactor bool } const ( @@ -159,6 +161,7 @@ const ( FlagEnableHasBlockPartMsg = "enable-blockpart-ack" FlagDebugGcInterval = "debug.gc-interval" FlagCommitGapOffset = "commit-gap-offset" + FlagEnableMempoolSimGuFactor = "enable-mem-sim-gu-factor" ) var ( @@ -308,6 +311,7 @@ func (c *OecConfig) loadFromConfig() { c.SetEnableHasBlockPartMsg(viper.GetBool(FlagEnableHasBlockPartMsg)) c.SetGcInterval(viper.GetInt(FlagDebugGcInterval)) c.SetIavlAcNoBatch(viper.GetBool(tmiavl.FlagIavlCommitAsyncNoBatch)) + c.SetEnableMempoolSimGuFactor(viper.GetBool(FlagEnableMempoolSimGuFactor)) } func resolveNodeKeyWhitelist(plain string) []string { @@ -380,6 +384,7 @@ func (c *OecConfig) format() string { commit-gap-height: %d enable-analyzer: %v iavl-commit-async-no-batch: %v + enable-mempool-sim-gu-factor: %v active-view-change: %v`, system.ChainName, c.GetMempoolRecheck(), c.GetMempoolForceRecheckGap(), @@ -409,6 +414,7 @@ func (c *OecConfig) format() string { c.GetCommitGapHeight(), c.GetEnableAnalyzer(), c.GetIavlAcNoBatch(), + c.GetEnableMempoolSimGuFactor(), c.GetActiveVC(), ) } @@ -658,6 +664,12 @@ func (c *OecConfig) updateFromKVStr(k, v string) { return } c.SetCommitGapOffset(r) + case FlagEnableMempoolSimGuFactor: + r, err := strconv.ParseBool(v) + if err != nil { + return + } + c.SetEnableMempoolSimGuFactor(r) } } @@ -1075,3 +1087,11 @@ func (c *OecConfig) GetIavlAcNoBatch() bool { func (c *OecConfig) SetIavlAcNoBatch(value bool) { c.iavlAcNoBatch = value } + +func (c *OecConfig) SetEnableMempoolSimGuFactor(v bool) { + c.enableMempoolSimGuFactor = v +} + +func (c *OecConfig) GetEnableMempoolSimGuFactor() bool { + return c.enableMempoolSimGuFactor +} diff --git a/cmd/client/flags.go b/cmd/client/flags.go index ad9467d5db..7c892c466d 100644 --- a/cmd/client/flags.go +++ b/cmd/client/flags.go @@ -69,6 +69,7 @@ func RegisterAppFlag(cmd *cobra.Command) { cmd.Flags().Int(config.FlagDynamicGpCheckBlocks, 5, "The recommended number of blocks checked of dynamic gas price [1,100])") cmd.Flags().Int(config.FlagDynamicGpCoefficient, 1, "Adjustment coefficient of dynamic gas price [1,100])") cmd.Flags().Int(config.FlagDynamicGpMode, tmtypes.MinimalGpMode, "Dynamic gas price mode (0: higher price|1: normal price|2: minimal price) is used to manage flags") + cmd.Flags().Bool(config.FlagEnableMempoolSimGuFactor, true, "Enable mempool simulate gas used is after the gu_factor(false is mean the simulate gas used is no has gu_factor)") cmd.Flags().Bool(config.FlagEnableHasBlockPartMsg, false, "Enable peer to broadcast HasBlockPartMessage") cmd.Flags().Bool(eth.FlagEnableMultiCall, false, "Enable node to support the eth_multiCall RPC API") diff --git a/libs/cosmos-sdk/baseapp/abci.go b/libs/cosmos-sdk/baseapp/abci.go index 186b33784b..079ccdd004 100644 --- a/libs/cosmos-sdk/baseapp/abci.go +++ b/libs/cosmos-sdk/baseapp/abci.go @@ -480,6 +480,15 @@ func handleSimulate(app *BaseApp, path []string, height int64, txBytes []byte, o return res, shouldAddBuffer, err } } + + if isMempoolSim { + gInfo, res, _ := app.MempoolSimulate(txBytes, tx, height, overrideBytes, from) + return sdk.SimulationResponse{ + GasInfo: gInfo, + Result: res, + }, shouldAddBuffer, nil + } + gInfo, res, err := app.Simulate(txBytes, tx, height, overrideBytes, from) if err != nil && !isMempoolSim { return sdk.SimulationResponse{}, false, sdkerrors.Wrap(err, "failed to simulate tx") diff --git a/libs/cosmos-sdk/baseapp/baseapp_mode_base.go b/libs/cosmos-sdk/baseapp/baseapp_mode_base.go index ecf1d3b735..2af8d41dd7 100644 --- a/libs/cosmos-sdk/baseapp/baseapp_mode_base.go +++ b/libs/cosmos-sdk/baseapp/baseapp_mode_base.go @@ -100,7 +100,7 @@ type modeHandlerSimulate struct { *modeHandlerBase } -//modeHandlerTrace derived from modeHandlerDeliver +// modeHandlerTrace derived from modeHandlerDeliver type modeHandlerTrace struct { *modeHandlerDeliver } @@ -164,15 +164,15 @@ func (m *modeHandlerBase) handleRunMsg(info *runTxInfo) (err error) { return } -//============================= +// ============================= // 4. handleDeferGasConsumed func (m *modeHandlerBase) handleDeferGasConsumed(*runTxInfo) {} -//==================================================================== +// ==================================================================== // 5. handleDeferRefund func (m *modeHandlerBase) handleDeferRefund(*runTxInfo) {} -//=========================================================================================== +// =========================================================================================== // other members func (m *modeHandlerBase) setGasConsumed(info *runTxInfo) { info.ctx.BlockGasMeter().ConsumeGas(info.ctx.GasMeter().GasConsumedToLimit(), "block gas meter") diff --git a/libs/cosmos-sdk/baseapp/baseapp_mode_simulate.go b/libs/cosmos-sdk/baseapp/baseapp_mode_simulate.go index 8d439f21dd..c577376812 100644 --- a/libs/cosmos-sdk/baseapp/baseapp_mode_simulate.go +++ b/libs/cosmos-sdk/baseapp/baseapp_mode_simulate.go @@ -21,6 +21,9 @@ func (m *modeHandlerSimulate) handleStartHeight(info *runTxInfo, height int64) e fmt.Sprintf("height(%d) should be greater than start block height(%d)", height, startHeight)) } else if height > startHeight && height <= lastHeight { info.ctx, err = app.getContextForSimTx(info.txBytes, height) + if m.mode == runTxModeSimulate && info.mempoolSimulate { + info.ctx.SetMempoolSimulate(true) + } } else { err = sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, fmt.Sprintf("height(%d) should be less than or equal to latest block height(%d)", height, lastHeight)) diff --git a/libs/cosmos-sdk/baseapp/baseapp_parallel.go b/libs/cosmos-sdk/baseapp/baseapp_parallel.go index 17754d1c3f..fe92514b9e 100644 --- a/libs/cosmos-sdk/baseapp/baseapp_parallel.go +++ b/libs/cosmos-sdk/baseapp/baseapp_parallel.go @@ -334,8 +334,8 @@ func (app *BaseApp) endParallelTxs(txSize int) [][]byte { return app.logFix(txs, logIndex, hasEnterEvmTx, errs, resp) } -//we reuse the nonce that changed by the last async call -//if last ante handler has been failed, we need rerun it ? or not? +// we reuse the nonce that changed by the last async call +// if last ante handler has been failed, we need rerun it ? or not? func (app *BaseApp) deliverTxWithCache(txIndex int) *executeResult { app.parallelTxManage.currentRerunIndex = txIndex defer func() { diff --git a/libs/cosmos-sdk/baseapp/baseapp_runtx.go b/libs/cosmos-sdk/baseapp/baseapp_runtx.go index 2771f8e28a..cf10b01874 100644 --- a/libs/cosmos-sdk/baseapp/baseapp_runtx.go +++ b/libs/cosmos-sdk/baseapp/baseapp_runtx.go @@ -34,7 +34,8 @@ type runTxInfo struct { reusableCacheMultiStore sdk.CacheMultiStore overridesBytes []byte - outOfGas bool + outOfGas bool + mempoolSimulate bool // for judge this sim is from mempool } func (info *runTxInfo) GetCacheMultiStore() (sdk.CacheMultiStore, bool) { diff --git a/libs/cosmos-sdk/baseapp/helpers.go b/libs/cosmos-sdk/baseapp/helpers.go index 9dc44f15e2..338d7e150c 100644 --- a/libs/cosmos-sdk/baseapp/helpers.go +++ b/libs/cosmos-sdk/baseapp/helpers.go @@ -1,6 +1,7 @@ package baseapp import ( + cfg "github.com/okex/exchain/libs/tendermint/config" "regexp" abci "github.com/okex/exchain/libs/tendermint/abci/types" @@ -23,6 +24,18 @@ func (app *BaseApp) Simulate(txBytes []byte, tx sdk.Tx, height int64, overridesB return info.gInfo, info.result, e } +func (app *BaseApp) MempoolSimulate(txBytes []byte, tx sdk.Tx, height int64, overridesBytes []byte, from ...string) (sdk.GasInfo, *sdk.Result, error) { + info := &runTxInfo{ + overridesBytes: overridesBytes, + mempoolSimulate: true, + } + if cfg.DynamicConfig.GetEnableMempoolSimGuFactor() { + info.mempoolSimulate = false // the mempoolSimulate is false is need gu factor + } + e := app.runtxWithInfo(info, runTxModeSimulate, txBytes, tx, height, from...) + return info.gInfo, info.result, e +} + func (app *BaseApp) Deliver(tx sdk.Tx) (sdk.GasInfo, *sdk.Result, error) { info, e := app.runTx(runTxModeDeliver, nil, tx, LatestSimulateTxHeight) return info.gInfo, info.result, e diff --git a/libs/cosmos-sdk/types/context.go b/libs/cosmos-sdk/types/context.go index 0f4548de91..b069d05b76 100644 --- a/libs/cosmos-sdk/types/context.go +++ b/libs/cosmos-sdk/types/context.go @@ -58,6 +58,7 @@ type Context struct { statedb vm.StateDB outOfGas bool + mempoolSimulate bool // if mempoolSimulate = true, then is mempool simulate tx } // Proposed rename, not done to avoid API breakage @@ -563,6 +564,14 @@ func (c Context) Value(key interface{}) interface{} { return c.ctx.Value(key) } +func (c *Context) SetMempoolSimulate(v bool) { + c.mempoolSimulate = v +} + +func (c *Context) IsMempoolSimulate() bool { + return c.mempoolSimulate +} + func (c *Context) SetOutOfGas(v bool) { c.outOfGas = v } diff --git a/libs/tendermint/config/dynamic_config_okchain.go b/libs/tendermint/config/dynamic_config_okchain.go index c69bea78a7..34843f27a4 100644 --- a/libs/tendermint/config/dynamic_config_okchain.go +++ b/libs/tendermint/config/dynamic_config_okchain.go @@ -34,6 +34,7 @@ type IDynamicConfig interface { GetDynamicGpMaxTxNum() int64 GetDynamicGpMaxGasUsed() int64 GetGasLimitBuffer() uint64 + GetEnableMempoolSimGuFactor() bool } var DynamicConfig IDynamicConfig = MockDynamicConfig{} @@ -190,3 +191,7 @@ func (d MockDynamicConfig) GetDynamicGpMaxGasUsed() int64 { func (d MockDynamicConfig) GetGasLimitBuffer() uint64 { return 0 } + +func (d MockDynamicConfig) GetEnableMempoolSimGuFactor() bool { + return false +} diff --git a/x/evm/types/state_transition.go b/x/evm/types/state_transition.go index e77c164c49..f7a2b05a49 100644 --- a/x/evm/types/state_transition.go +++ b/x/evm/types/state_transition.go @@ -254,7 +254,7 @@ func (st StateTransition) TransitionDb(ctx sdk.Context, config ChainConfig) (exe contractAddressStr := EthAddressToString(&contractAddress) recipientLog = strings.Join([]string{"contract address ", contractAddressStr}, "") gasConsumed = gasLimit - leftOverGas - if !csdb.GuFactor.IsNegative() { + if !ctx.IsMempoolSimulate() && !csdb.GuFactor.IsNegative() { gasConsumed = csdb.GuFactor.MulInt(sdk.NewIntFromUint64(gasConsumed)).TruncateInt().Uint64() } //if no err, we must be check weather out of gas because, we may increase gasConsumed by 'csdb.GuFactor'. @@ -294,7 +294,7 @@ func (st StateTransition) TransitionDb(ctx sdk.Context, config ChainConfig) (exe recipientLog = strings.Join([]string{"recipient address ", recipientStr}, "") gasConsumed = gasLimit - leftOverGas - if !csdb.GuFactor.IsNegative() { + if !ctx.IsMempoolSimulate() && !csdb.GuFactor.IsNegative() { gasConsumed = csdb.GuFactor.MulInt(sdk.NewIntFromUint64(gasConsumed)).TruncateInt().Uint64() } //if no err, we must be check weather out of gas because, we may increase gasConsumed by 'csdb.GuFactor'.