diff --git a/libs/cosmos-sdk/baseapp/abci.go b/libs/cosmos-sdk/baseapp/abci.go index bb2647c531..9bbd4ba527 100644 --- a/libs/cosmos-sdk/baseapp/abci.go +++ b/libs/cosmos-sdk/baseapp/abci.go @@ -445,51 +445,70 @@ func handleSimulate(app *BaseApp, path []string, height int64, txBytes []byte, o } } if isPureWasm { - wasmSimulator := simulator.NewWasmSimulator() - defer wasmSimulator.Release() + return handleSimulateWasm(height, txBytes, msgs) + } + } + gInfo, res, err := app.Simulate(txBytes, tx, height, overrideBytes, from) - 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")) - } + // 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")) + } + + simRes := sdk.SimulationResponse{ + GasInfo: gInfo, + Result: res, + } + + return abci.ResponseQuery{ + Codespace: sdkerrors.RootCodespace, + Height: height, + Value: codec.Cdc.MustMarshalBinaryBare(simRes), + } +} +func handleSimulateWasm(height int64, txBytes []byte, msgs []sdk.Msg) (abciRes abci.ResponseQuery) { + wasmSimulator := simulator.NewWasmSimulator() + defer wasmSimulator.Release() + defer func() { + if r := recover(); r != nil { gasMeter := wasmSimulator.Context().GasMeter() simRes := sdk.SimulationResponse{ GasInfo: sdk.GasInfo{ GasUsed: gasMeter.GasConsumed(), }, - Result: res, } - return abci.ResponseQuery{ + abciRes = abci.ResponseQuery{ Codespace: sdkerrors.RootCodespace, Height: height, Value: codec.Cdc.MustMarshalBinaryBare(simRes), } } + }() - } - 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")) + 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")) } + gasMeter := wasmSimulator.Context().GasMeter() simRes := sdk.SimulationResponse{ - GasInfo: gInfo, - Result: res, + GasInfo: sdk.GasInfo{ + GasUsed: gasMeter.GasConsumed(), + }, + Result: res, } - return abci.ResponseQuery{ Codespace: sdkerrors.RootCodespace, Height: height, Value: codec.Cdc.MustMarshalBinaryBare(simRes), } } + func handleQueryApp(app *BaseApp, path []string, req abci.RequestQuery) abci.ResponseQuery { if len(path) >= 2 { switch path[1] { diff --git a/libs/tendermint/mempool/clist_mempool.go b/libs/tendermint/mempool/clist_mempool.go index 1c8a9a1a4d..9726623c39 100644 --- a/libs/tendermint/mempool/clist_mempool.go +++ b/libs/tendermint/mempool/clist_mempool.go @@ -344,16 +344,8 @@ func (mem *CListMempool) CheckTx(tx types.Tx, cb func(*abci.Response), txInfo Tx defer mem.updateMtx.RUnlock() var err error - var gasUsed int64 if cfg.DynamicConfig.GetMaxGasUsedPerBlock() > -1 { - gasUsed = mem.txInfoparser.GetTxHistoryGasUsed(tx) - if gasUsed < 0 { - simuRes, err := mem.simulateTx(tx) - if err != nil { - return err - } - gasUsed = int64(simuRes.GasUsed) - } + txInfo.gasUsed = mem.txInfoparser.GetTxHistoryGasUsed(tx) } if mem.preCheck != nil { @@ -371,16 +363,16 @@ func (mem *CListMempool) CheckTx(tx types.Tx, cb func(*abci.Response), txInfo Tx types.SignatureCache().Add(txkey[:], txInfo.from) } reqRes := mem.proxyAppConn.CheckTxAsync(abci.RequestCheckTx{Tx: tx, Type: txInfo.checkType, From: txInfo.wtx.GetFrom(), Nonce: nonce}) - if cfg.DynamicConfig.GetMaxGasUsedPerBlock() > -1 { - if r, ok := reqRes.Response.Value.(*abci.Response_CheckTx); ok { + if r, ok := reqRes.Response.Value.(*abci.Response_CheckTx); ok { + if txInfo.gasUsed <= 0 || txInfo.gasUsed > r.CheckTx.GasWanted { + txInfo.gasUsed = r.CheckTx.GasWanted + } + if cfg.DynamicConfig.GetMaxGasUsedPerBlock() > -1 { mem.logger.Info(fmt.Sprintf("mempool.SimulateTx: txhash<%s>, gasLimit<%d>, gasUsed<%d>", - hex.EncodeToString(tx.Hash(mem.Height())), r.CheckTx.GasWanted, gasUsed)) - if gasUsed < r.CheckTx.GasWanted { - r.CheckTx.GasWanted = gasUsed - } - + hex.EncodeToString(tx.Hash(mem.Height())), r.CheckTx.GasWanted, txInfo.gasUsed)) } } + reqRes.SetCallback(mem.reqResCb(tx, txInfo, cb)) atomic.AddInt64(&mem.checkCnt, 1) @@ -702,7 +694,8 @@ func (mem *CListMempool) resCbFirstTime( memTx := &mempoolTx{ height: mem.Height(), - gasWanted: r.CheckTx.GasWanted, + gasLimit: r.CheckTx.GasWanted, + gasWanted: txInfo.gasUsed, tx: tx, realTx: r.CheckTx.Tx, nodeKey: txInfo.wtx.GetNodeKey(), @@ -1245,8 +1238,9 @@ func MultiPriceBump(rawPrice *big.Int, priceBump int64) *big.Int { // mempoolTx is a transaction that successfully ran type mempoolTx struct { - height int64 // height that this tx had been validated in - gasWanted int64 // amount of gas this tx states it will require + height int64 // height that this tx had been validated in + gasWanted int64 // amount of gas this tx states it will require + gasLimit int64 tx types.Tx // realTx abci.TxEssentials nodeKey []byte @@ -1447,10 +1441,10 @@ func (mem *CListMempool) simulationJob(memTx *mempoolTx) { return } gas := int64(simuRes.GasUsed) * int64(cfg.DynamicConfig.GetPGUAdjustment()*100) / 100 - atomic.StoreInt64(&memTx.gasWanted, gas) - if gas < atomic.LoadInt64(&memTx.gasWanted) { + if gas < atomic.LoadInt64(&memTx.gasLimit) { atomic.StoreInt64(&memTx.gasWanted, gas) } + atomic.AddUint32(&memTx.isSim, 1) mem.gasCache.Add(hex.EncodeToString(memTx.realTx.TxHash()), gas) } diff --git a/libs/tendermint/mempool/mempool.go b/libs/tendermint/mempool/mempool.go index 87cab9c05c..d9fed37d81 100644 --- a/libs/tendermint/mempool/mempool.go +++ b/libs/tendermint/mempool/mempool.go @@ -119,6 +119,8 @@ type TxInfo struct { wtx *WrappedTx checkType abci.CheckTxType + gasUsed int64 + wrapCMTx *types.WrapCMTx }