Skip to content

Commit

Permalink
limit gas used (#80)
Browse files Browse the repository at this point in the history
* limit gas used

* limit gas used

* limit gas used

* add log for limit gas used

* limit gas used

* optimize flag

* optimize flag

* fix ut

* fix ut

* fix ut
  • Loading branch information
xiangjianmeng committed Oct 11, 2021
1 parent 68d67ac commit cefe132
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 0 deletions.
5 changes: 5 additions & 0 deletions cmd/tendermint/commands/run_node.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,11 @@ func AddNodeFlags(cmd *cobra.Command) {
config.Mempool.MaxTxNumPerBlock,
"Maximum number of transactions in a block",
)
cmd.Flags().Int64(
"mempool.max_gas_used_per_block",
config.Mempool.MaxGasUsedPerBlock,
"Maximum gas used of transactions in a block",
)
cmd.Flags().Bool(
"mempool.sort_tx_by_gp",
config.Mempool.SortTxByGp,
Expand Down
2 changes: 2 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -668,6 +668,7 @@ type MempoolConfig struct {
CacheSize int `mapstructure:"cache_size"`
MaxTxBytes int `mapstructure:"max_tx_bytes"`
MaxTxNumPerBlock int64 `mapstructure:"max_tx_num_per_block"`
MaxGasUsedPerBlock int64 `mapstructure:"max_gas_used_per_block"`
SortTxByGp bool `mapstructure:"sort_tx_by_gp"`
ForceRecheckGap int64 `mapstructure:"force_recheck_gap"`
TxPriceBump uint64 `mapstructure:"tx_price_bump"`
Expand All @@ -691,6 +692,7 @@ func DefaultMempoolConfig() *MempoolConfig {
CacheSize: 10000,
MaxTxBytes: 1024 * 1024, // 1MB
MaxTxNumPerBlock: 300,
MaxGasUsedPerBlock: -1,
SortTxByGp: true,
ForceRecheckGap: 200,
TxPriceBump: 10,
Expand Down
27 changes: 27 additions & 0 deletions mempool/clist_mempool.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"bytes"
"container/list"
"crypto/sha256"
"encoding/hex"
"encoding/json"
"fmt"
"math/big"
Expand Down Expand Up @@ -267,6 +268,12 @@ func (mem *CListMempool) TxsWaitChan() <-chan struct{} {
//
// Safe for concurrent use by multiple goroutines.
func (mem *CListMempool) CheckTx(tx types.Tx, cb func(*abci.Response), txInfo TxInfo) error {
var simuRes *SimulationResponse
var err error
if mem.config.MaxGasUsedPerBlock > -1 {
simuRes, err = mem.simulateTx(tx)
}

mem.updateMtx.RLock()
// use defer to unlock mutex because application (*local client*) might panic
defer mem.updateMtx.RUnlock()
Expand Down Expand Up @@ -329,6 +336,13 @@ func (mem *CListMempool) CheckTx(tx types.Tx, cb func(*abci.Response), txInfo Tx
}

reqRes := mem.proxyAppConn.CheckTxAsync(abci.RequestCheckTx{Tx: tx})
if mem.config.MaxGasUsedPerBlock > -1 {
if r, ok := reqRes.Response.Value.(*abci.Response_CheckTx); ok && err == nil {
mem.logger.Info(fmt.Sprintf("mempool.SimulateTx: txhash<%s>, gasLimit<%d>, gasUsed<%d>",
hex.EncodeToString(tx.Hash()), r.CheckTx.GasWanted, simuRes.GasUsed))
r.CheckTx.GasWanted = int64(simuRes.GasUsed)
}
}
reqRes.SetCallback(mem.reqResCb(tx, txInfo.SenderID, txInfo.SenderP2PID, cb))

return nil
Expand Down Expand Up @@ -1183,3 +1197,16 @@ func (mem *CListMempool) pendingPoolJob() {
"addressNonceMap", addrNonceMap)
}
}

func (mem *CListMempool) simulateTx(tx types.Tx) (*SimulationResponse, error) {
var simuRes SimulationResponse
res, err := mem.proxyAppConn.QuerySync(abci.RequestQuery{
Path: "app/simulate/mempool",
Data: tx,
})
if err != nil {
return nil, err
}
err = cdc.UnmarshalBinaryBare(res.Value, &simuRes)
return &simuRes, err
}
33 changes: 33 additions & 0 deletions mempool/exchain_simulate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package mempool

import abci "github.com/tendermint/tendermint/abci/types"

// SimulationResponse defines the response generated when a transaction is successfully
// simulated by the Baseapp.
type SimulationResponse struct {
GasInfo
Result *Result
}

// GasInfo defines tx execution gas context.
type GasInfo struct {
// GasWanted is the maximum units of work we allow this tx to perform.
GasWanted uint64

// GasUsed is the amount of gas actually consumed.
GasUsed uint64
}

// Result is the union of ResponseFormat and ResponseCheckTx.
type Result struct {
// Data is any data returned from message or handler execution. It MUST be length
// prefixed in order to separate data from multiple message executions.
Data []byte

// Log contains the log information from message or handler execution.
Log string

// Events contains a slice of Event objects that were emitted during message or
// handler execution.
Events []abci.Event
}
6 changes: 6 additions & 0 deletions proxy/app_conn.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ type AppConnMempool interface {
FlushSync() error

SetOptionAsync(types.RequestSetOption) *abcicli.ReqRes

QuerySync(req types.RequestQuery) (*types.ResponseQuery, error)
}

type AppConnQuery interface {
Expand Down Expand Up @@ -125,6 +127,10 @@ func (app *appConnMempool) SetOptionAsync(req types.RequestSetOption) *abcicli.R
return app.appConn.SetOptionAsync(req)
}

func (app *appConnMempool) QuerySync(req types.RequestQuery) (*types.ResponseQuery, error) {
return app.appConn.QuerySync(req)
}

//------------------------------------------------
// Implements AppConnQuery (subset of abcicli.Client)

Expand Down
3 changes: 3 additions & 0 deletions state/execution.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,9 @@ func (blockExec *BlockExecutor) CreateProposalBlock(

// Fetch a limited amount of valid txs
maxDataBytes := types.MaxDataBytes(maxBytes, state.Validators.Size(), len(evidence))
if blockExec.mempool.GetConfig().MaxGasUsedPerBlock > -1 {
maxGas = blockExec.mempool.GetConfig().MaxGasUsedPerBlock
}
txs := blockExec.mempool.ReapMaxBytesMaxGas(maxDataBytes, maxGas)

return state.MakeBlock(height, txs, commit, evidence, proposerAddr)
Expand Down

0 comments on commit cefe132

Please sign in to comment.