Co-authored-by: Dev Ojha <ValarDragon@users.noreply.github.com>
This commit is contained in:
+2
-1
@@ -1116,7 +1116,8 @@ func (app *BaseApp) CreateQueryContext(height int64, prove bool) (sdk.Context, e
|
||||
// branch the commit multi-store for safety
|
||||
ctx := sdk.NewContext(cacheMS, app.checkState.ctx.BlockHeader(), true, app.logger).
|
||||
WithMinGasPrices(app.minGasPrices).
|
||||
WithBlockHeight(height)
|
||||
WithBlockHeight(height).
|
||||
WithGasMeter(storetypes.NewGasMeter(app.queryGasLimit))
|
||||
|
||||
if height != lastBlockHeight {
|
||||
rms, ok := app.cms.(*rootmulti.Store)
|
||||
|
||||
@@ -3,6 +3,7 @@ package baseapp
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math"
|
||||
"sort"
|
||||
"strconv"
|
||||
|
||||
@@ -123,6 +124,9 @@ type BaseApp struct {
|
||||
// application parameter store.
|
||||
paramStore ParamStore
|
||||
|
||||
// queryGasLimit defines the maximum gas for queries; unbounded if 0.
|
||||
queryGasLimit uint64
|
||||
|
||||
// The minimum gas prices a validator is willing to accept for processing a
|
||||
// transaction. This is mainly used for DoS and spam prevention.
|
||||
minGasPrices sdk.DecCoins
|
||||
@@ -192,6 +196,7 @@ func NewBaseApp(
|
||||
msgServiceRouter: NewMsgServiceRouter(),
|
||||
txDecoder: txDecoder,
|
||||
fauxMerkleMode: false,
|
||||
queryGasLimit: math.MaxUint64,
|
||||
}
|
||||
|
||||
for _, option := range options {
|
||||
|
||||
@@ -85,6 +85,26 @@ func NewBaseAppSuite(t *testing.T, opts ...func(*baseapp.BaseApp)) *BaseAppSuite
|
||||
}
|
||||
}
|
||||
|
||||
func getQueryBaseapp(t *testing.T) *baseapp.BaseApp {
|
||||
t.Helper()
|
||||
|
||||
db := dbm.NewMemDB()
|
||||
name := t.Name()
|
||||
app := baseapp.NewBaseApp(name, log.NewTestLogger(t), db, nil)
|
||||
|
||||
_, err := app.FinalizeBlock(&abci.RequestFinalizeBlock{Height: 1})
|
||||
require.NoError(t, err)
|
||||
_, err = app.Commit()
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = app.FinalizeBlock(&abci.RequestFinalizeBlock{Height: 2})
|
||||
require.NoError(t, err)
|
||||
_, err = app.Commit()
|
||||
require.NoError(t, err)
|
||||
|
||||
return app
|
||||
}
|
||||
|
||||
func NewBaseAppSuiteWithSnapshots(t *testing.T, cfg SnapshotsConfig, opts ...func(*baseapp.BaseApp)) *BaseAppSuite {
|
||||
snapshotTimeout := 1 * time.Minute
|
||||
snapshotStore, err := snapshots.NewStore(dbm.NewMemDB(), testutil.GetTempDir(t))
|
||||
@@ -614,6 +634,60 @@ func TestSetMinGasPrices(t *testing.T) {
|
||||
require.Equal(t, minGasPrices, ctx.MinGasPrices())
|
||||
}
|
||||
|
||||
type ctxType string
|
||||
|
||||
const (
|
||||
QueryCtx ctxType = "query"
|
||||
CheckTxCtx ctxType = "checkTx"
|
||||
)
|
||||
|
||||
var ctxTypes = []ctxType{QueryCtx, CheckTxCtx}
|
||||
|
||||
func (c ctxType) GetCtx(t *testing.T, bapp *baseapp.BaseApp) sdk.Context {
|
||||
t.Helper()
|
||||
if c == QueryCtx {
|
||||
ctx, err := bapp.CreateQueryContext(1, false)
|
||||
require.NoError(t, err)
|
||||
return ctx
|
||||
} else if c == CheckTxCtx {
|
||||
return getCheckStateCtx(bapp)
|
||||
}
|
||||
// TODO: Not supported yet
|
||||
return getFinalizeBlockStateCtx(bapp)
|
||||
}
|
||||
|
||||
func TestQueryGasLimit(t *testing.T) {
|
||||
testCases := []struct {
|
||||
queryGasLimit uint64
|
||||
gasActuallyUsed uint64
|
||||
shouldQueryErr bool
|
||||
}{
|
||||
{queryGasLimit: 100, gasActuallyUsed: 50, shouldQueryErr: false}, // Valid case
|
||||
{queryGasLimit: 100, gasActuallyUsed: 150, shouldQueryErr: true}, // gasActuallyUsed > queryGasLimit
|
||||
{queryGasLimit: 0, gasActuallyUsed: 50, shouldQueryErr: false}, // fuzzing with queryGasLimit = 0
|
||||
{queryGasLimit: 0, gasActuallyUsed: 0, shouldQueryErr: false}, // both queryGasLimit and gasActuallyUsed are 0
|
||||
{queryGasLimit: 200, gasActuallyUsed: 200, shouldQueryErr: false}, // gasActuallyUsed == queryGasLimit
|
||||
{queryGasLimit: 100, gasActuallyUsed: 1000, shouldQueryErr: true}, // gasActuallyUsed > queryGasLimit
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
for _, ctxType := range ctxTypes {
|
||||
t.Run(fmt.Sprintf("%s: %d - %d", ctxType, tc.queryGasLimit, tc.gasActuallyUsed), func(t *testing.T) {
|
||||
app := getQueryBaseapp(t)
|
||||
baseapp.SetQueryGasLimit(tc.queryGasLimit)(app)
|
||||
ctx := ctxType.GetCtx(t, app)
|
||||
|
||||
// query gas limit should have no effect when CtxType != QueryCtx
|
||||
if tc.shouldQueryErr && ctxType == QueryCtx {
|
||||
require.Panics(t, func() { ctx.GasMeter().ConsumeGas(tc.gasActuallyUsed, "test") })
|
||||
} else {
|
||||
require.NotPanics(t, func() { ctx.GasMeter().ConsumeGas(tc.gasActuallyUsed, "test") })
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetMaximumBlockGas(t *testing.T) {
|
||||
suite := NewBaseAppSuite(t)
|
||||
_, err := suite.baseApp.InitChain(&abci.RequestInitChain{})
|
||||
|
||||
@@ -3,6 +3,7 @@ package baseapp
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"math"
|
||||
|
||||
dbm "github.com/cosmos/cosmos-db"
|
||||
|
||||
@@ -36,6 +37,15 @@ func SetMinGasPrices(gasPricesStr string) func(*BaseApp) {
|
||||
return func(bapp *BaseApp) { bapp.setMinGasPrices(gasPrices) }
|
||||
}
|
||||
|
||||
// SetQueryGasLimit returns an option that sets a gas limit for queries.
|
||||
func SetQueryGasLimit(queryGasLimit uint64) func(*BaseApp) {
|
||||
if queryGasLimit == 0 {
|
||||
queryGasLimit = math.MaxUint64
|
||||
}
|
||||
|
||||
return func(bapp *BaseApp) { bapp.queryGasLimit = queryGasLimit }
|
||||
}
|
||||
|
||||
// SetHaltHeight returns a BaseApp option function that sets the halt block height.
|
||||
func SetHaltHeight(blockHeight uint64) func(*BaseApp) {
|
||||
return func(bapp *BaseApp) { bapp.setHaltHeight(blockHeight) }
|
||||
|
||||
Reference in New Issue
Block a user