Skip to content

Commit

Permalink
add gas limit buffer to cmtx (#3105)
Browse files Browse the repository at this point in the history
* add gas limit buffer to cmtx

* update
  • Loading branch information
yann-sjtu authored Apr 14, 2023
1 parent ef775ac commit b7f3994
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 36 deletions.
84 changes: 48 additions & 36 deletions libs/cosmos-sdk/baseapp/abci.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,6 @@ import (
"syscall"
"time"

"github.com/spf13/viper"
"github.com/tendermint/go-amino"

"github.com/okex/exchain/app/rpc/simulator"
"github.com/okex/exchain/libs/cosmos-sdk/codec"
"github.com/okex/exchain/libs/cosmos-sdk/store/mpt"
Expand All @@ -24,7 +21,10 @@ import (
"github.com/okex/exchain/libs/system/trace"
"github.com/okex/exchain/libs/system/trace/persist"
abci "github.com/okex/exchain/libs/tendermint/abci/types"
cfg "github.com/okex/exchain/libs/tendermint/config"
tmtypes "github.com/okex/exchain/libs/tendermint/types"
"github.com/spf13/viper"
"github.com/tendermint/go-amino"
)

// InitChain implements the ABCI interface. It runs the initialization logic
Expand Down Expand Up @@ -410,7 +410,31 @@ func (app *BaseApp) Query(req abci.RequestQuery) abci.ResponseQuery {
return sdkerrors.QueryResult(sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, "unknown query path"))
}
}
func handleSimulate(app *BaseApp, path []string, height int64, txBytes []byte, overrideBytes []byte) abci.ResponseQuery {

func handleSimulateWithBuffer(app *BaseApp, path []string, height int64, txBytes []byte, overrideBytes []byte) abci.ResponseQuery {
simRes, shouldAddBuffer, err := handleSimulate(app, path, height, txBytes, overrideBytes)
if err != nil {
return sdkerrors.QueryResult(err)
}
if shouldAddBuffer {
buffer := cfg.DynamicConfig.GetGasLimitBuffer()
gasUsed := simRes.GasUsed
gasUsed += gasUsed * buffer / 100
if gasUsed > SimulationGasLimit {
gasUsed = SimulationGasLimit
}
simRes.GasUsed = gasUsed
}

return abci.ResponseQuery{
Codespace: sdkerrors.RootCodespace,
Height: height,
Value: codec.Cdc.MustMarshalBinaryBare(simRes),
}

}

func handleSimulate(app *BaseApp, path []string, height int64, txBytes []byte, overrideBytes []byte) (sdk.SimulationResponse, bool, error) {
// if path contains address, it means 'eth_estimateGas' the sender
hasExtraPaths := len(path) > 2
var from string
Expand All @@ -430,9 +454,16 @@ func handleSimulate(app *BaseApp, path []string, height int64, txBytes []byte, o
if tx == nil {
tx, err = app.txDecoder(txBytes)
if err != nil {
return sdkerrors.QueryResult(sdkerrors.Wrap(err, "failed to decode tx"))
return sdk.SimulationResponse{}, false, sdkerrors.Wrap(err, "failed to decode tx")
}
}
// if path contains mempool, it means to enable MaxGasUsedPerBlock
// return the actual gasUsed even though simulate tx failed
isMempoolSim := hasExtraPaths && path[2] == "mempool"
var shouldAddBuffer bool
if !isMempoolSim && tx.GetType() != types.EvmTxType {
shouldAddBuffer = true
}

msgs := tx.GetMsgs()

Expand All @@ -445,83 +476,64 @@ func handleSimulate(app *BaseApp, path []string, height int64, txBytes []byte, o
}
}
if isPureWasm {
return handleSimulateWasm(height, txBytes, msgs)
res, err := handleSimulateWasm(height, txBytes, msgs)
return res, shouldAddBuffer, err
}
}
gInfo, res, err := app.Simulate(txBytes, tx, height, overrideBytes, from)

// if path contains mempool, it means to enable MaxGasUsedPerBlock
// return the actual gasUsed even though simulate tx failed
isMempoolSim := hasExtraPaths && path[2] == "mempool"
if err != nil && !isMempoolSim {
return sdkerrors.QueryResult(sdkerrors.Wrap(err, "failed to simulate tx"))
return sdk.SimulationResponse{}, false, sdkerrors.Wrap(err, "failed to simulate tx")
}

simRes := sdk.SimulationResponse{
return sdk.SimulationResponse{
GasInfo: gInfo,
Result: res,
}

return abci.ResponseQuery{
Codespace: sdkerrors.RootCodespace,
Height: height,
Value: codec.Cdc.MustMarshalBinaryBare(simRes),
}
}, shouldAddBuffer, nil
}

func handleSimulateWasm(height int64, txBytes []byte, msgs []sdk.Msg) (abciRes abci.ResponseQuery) {
func handleSimulateWasm(height int64, txBytes []byte, msgs []sdk.Msg) (simRes sdk.SimulationResponse, err error) {
wasmSimulator := simulator.NewWasmSimulator()
defer wasmSimulator.Release()
defer func() {
if r := recover(); r != nil {
gasMeter := wasmSimulator.Context().GasMeter()
simRes := sdk.SimulationResponse{
simRes = sdk.SimulationResponse{
GasInfo: sdk.GasInfo{
GasUsed: gasMeter.GasConsumed(),
},
}
abciRes = abci.ResponseQuery{
Codespace: sdkerrors.RootCodespace,
Height: height,
Value: codec.Cdc.MustMarshalBinaryBare(simRes),
}
}
}()

wasmSimulator.Context().GasMeter().ConsumeGas(73000, "general ante check cost")
wasmSimulator.Context().GasMeter().ConsumeGas(uint64(10*len(txBytes)), "tx size cost")
res, err := wasmSimulator.Simulate(msgs)
if err != nil {
return sdkerrors.QueryResult(sdkerrors.Wrap(err, "failed to simulate wasm tx"))
return sdk.SimulationResponse{}, sdkerrors.Wrap(err, "failed to simulate wasm tx")
}

gasMeter := wasmSimulator.Context().GasMeter()
simRes := sdk.SimulationResponse{
return sdk.SimulationResponse{
GasInfo: sdk.GasInfo{
GasUsed: gasMeter.GasConsumed(),
},
Result: res,
}
return abci.ResponseQuery{
Codespace: sdkerrors.RootCodespace,
Height: height,
Value: codec.Cdc.MustMarshalBinaryBare(simRes),
}
}, nil
}

func handleQueryApp(app *BaseApp, path []string, req abci.RequestQuery) abci.ResponseQuery {
if len(path) >= 2 {
switch path[1] {
case "simulate":
return handleSimulate(app, path, req.Height, req.Data, nil)
return handleSimulateWithBuffer(app, path, req.Height, req.Data, nil)

case "simulateWithOverrides":
queryBytes := req.Data
var queryData types.SimulateData
if err := json.Unmarshal(queryBytes, &queryData); err != nil {
return sdkerrors.QueryResult(sdkerrors.Wrap(err, "failed to decode simulateOverrideData"))
}
return handleSimulate(app, path, req.Height, queryData.TxBytes, queryData.OverridesBytes)
return handleSimulateWithBuffer(app, path, req.Height, queryData.TxBytes, queryData.OverridesBytes)

case "trace":
var queryParam sdk.QueryTraceTx
Expand Down
5 changes: 5 additions & 0 deletions libs/tendermint/config/dynamic_config_okchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ type IDynamicConfig interface {
GetDynamicGpMode() int
GetDynamicGpMaxTxNum() int64
GetDynamicGpMaxGasUsed() int64
GetGasLimitBuffer() uint64
}

var DynamicConfig IDynamicConfig = MockDynamicConfig{}
Expand Down Expand Up @@ -185,3 +186,7 @@ func (d *MockDynamicConfig) SetDynamicGpMaxGasUsed(value int64) {
func (d MockDynamicConfig) GetDynamicGpMaxGasUsed() int64 {
return d.dynamicGpMaxGasUsed
}

func (d MockDynamicConfig) GetGasLimitBuffer() uint64 {
return 0
}

0 comments on commit b7f3994

Please sign in to comment.