refactor!: abstractions for snapshot and pruning; snapshot intervals eventually pruned; unit tests (#11496)

This commit is contained in:
Roman
2022-04-21 15:30:36 -04:00
committed by GitHub
parent d4dd44469f
commit 42f8d45b68
57 changed files with 2643 additions and 638 deletions
+6 -36
View File
@@ -338,9 +338,7 @@ func (app *BaseApp) Commit() (res abci.ResponseCommit) {
app.halt()
}
if app.snapshotInterval > 0 && uint64(header.Height)%app.snapshotInterval == 0 {
go app.snapshot(header.Height)
}
go app.snapshotManager.SnapshotIfApplicable(header.Height)
return abci.ResponseCommit{
Data: commitID.Hash,
@@ -370,36 +368,6 @@ func (app *BaseApp) halt() {
os.Exit(0)
}
// snapshot takes a snapshot of the current state and prunes any old snapshottypes.
func (app *BaseApp) snapshot(height int64) {
if app.snapshotManager == nil {
app.logger.Info("snapshot manager not configured")
return
}
app.logger.Info("creating state snapshot", "height", height)
snapshot, err := app.snapshotManager.Create(uint64(height))
if err != nil {
app.logger.Error("failed to create state snapshot", "height", height, "err", err)
return
}
app.logger.Info("completed state snapshot", "height", height, "format", snapshot.Format)
if app.snapshotKeepRecent > 0 {
app.logger.Debug("pruning state snapshots")
pruned, err := app.snapshotManager.Prune(app.snapshotKeepRecent)
if err != nil {
app.logger.Error("Failed to prune state snapshots", "err", err)
return
}
app.logger.Debug("pruned state snapshots", "pruned", pruned)
}
}
// Query implements the ABCI interface. It delegates to CommitMultiStore if it
// implements Queryable.
func (app *BaseApp) Query(req abci.RequestQuery) (res abci.ResponseQuery) {
@@ -718,9 +686,11 @@ func (app *BaseApp) GetBlockRetentionHeight(commitHeight int64) int64 {
retentionHeight = commitHeight - cp.Evidence.MaxAgeNumBlocks
}
if app.snapshotInterval > 0 && app.snapshotKeepRecent > 0 {
v := commitHeight - int64((app.snapshotInterval * uint64(app.snapshotKeepRecent)))
retentionHeight = minNonZero(retentionHeight, v)
if app.snapshotManager != nil {
snapshotRetentionHeights := app.snapshotManager.GetSnapshotBlockRetentionHeights()
if snapshotRetentionHeights > 0 {
retentionHeight = minNonZero(retentionHeight, commitHeight-snapshotRetentionHeights)
}
}
v := commitHeight - int64(app.minRetainBlocks)
+19 -9
View File
@@ -5,11 +5,14 @@ import (
"github.com/stretchr/testify/require"
abci "github.com/tendermint/tendermint/abci/types"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
tmprototypes "github.com/tendermint/tendermint/proto/tendermint/types"
dbm "github.com/tendermint/tm-db"
"github.com/cosmos/cosmos-sdk/baseapp"
pruningtypes "github.com/cosmos/cosmos-sdk/pruning/types"
snapshottypes "github.com/cosmos/cosmos-sdk/snapshots/types"
"github.com/cosmos/cosmos-sdk/snapshots"
"github.com/cosmos/cosmos-sdk/testutil"
)
func TestGetBlockRentionHeight(t *testing.T) {
@@ -17,6 +20,9 @@ func TestGetBlockRentionHeight(t *testing.T) {
db := dbm.NewMemDB()
name := t.Name()
snapshotStore, err := snapshots.NewStore(dbm.NewMemDB(), testutil.GetTempDir(t))
require.NoError(t, err)
testCases := map[string]struct {
bapp *baseapp.BaseApp
maxAgeBlocks int64
@@ -38,17 +44,18 @@ func TestGetBlockRentionHeight(t *testing.T) {
"pruning iavl snapshot only": {
bapp: baseapp.NewBaseApp(
name, logger, db,
baseapp.SetPruning(pruningtypes.NewPruningOptions(pruningtypes.PruningNothing)),
baseapp.SetMinRetainBlocks(1),
baseapp.SetSnapshot(snapshotStore, snapshottypes.NewSnapshotOptions(10000, 1)),
),
maxAgeBlocks: 0,
commitHeight: 499000,
expected: 498999,
expected: 489000,
},
"pruning state sync snapshot only": {
bapp: baseapp.NewBaseApp(
name, logger, db,
baseapp.SetSnapshotInterval(50000),
baseapp.SetSnapshotKeepRecent(3),
baseapp.SetSnapshot(snapshotStore, snapshottypes.NewSnapshotOptions(50000, 3)),
baseapp.SetMinRetainBlocks(1),
),
maxAgeBlocks: 0,
@@ -67,8 +74,9 @@ func TestGetBlockRentionHeight(t *testing.T) {
"pruning all conditions": {
bapp: baseapp.NewBaseApp(
name, logger, db,
baseapp.SetPruning(pruningtypes.NewCustomPruningOptions(0, 0)),
baseapp.SetMinRetainBlocks(400000),
baseapp.SetSnapshotInterval(50000), baseapp.SetSnapshotKeepRecent(3),
baseapp.SetSnapshot(snapshotStore, snapshottypes.NewSnapshotOptions(50000, 3)),
),
maxAgeBlocks: 362880,
commitHeight: 499000,
@@ -77,8 +85,9 @@ func TestGetBlockRentionHeight(t *testing.T) {
"no pruning due to no persisted state": {
bapp: baseapp.NewBaseApp(
name, logger, db,
baseapp.SetPruning(pruningtypes.NewCustomPruningOptions(0, 0)),
baseapp.SetMinRetainBlocks(400000),
baseapp.SetSnapshotInterval(50000), baseapp.SetSnapshotKeepRecent(3),
baseapp.SetSnapshot(snapshotStore, snapshottypes.NewSnapshotOptions(50000, 3)),
),
maxAgeBlocks: 362880,
commitHeight: 10000,
@@ -87,8 +96,9 @@ func TestGetBlockRentionHeight(t *testing.T) {
"disable pruning": {
bapp: baseapp.NewBaseApp(
name, logger, db,
baseapp.SetPruning(pruningtypes.NewCustomPruningOptions(0, 0)),
baseapp.SetMinRetainBlocks(0),
baseapp.SetSnapshotInterval(50000), baseapp.SetSnapshotKeepRecent(3),
baseapp.SetSnapshot(snapshotStore, snapshottypes.NewSnapshotOptions(50000, 3)),
),
maxAgeBlocks: 362880,
commitHeight: 499000,
@@ -126,10 +136,10 @@ func TestBaseAppCreateQueryContext(t *testing.T) {
name := t.Name()
app := baseapp.NewBaseApp(name, logger, db)
app.BeginBlock(abci.RequestBeginBlock{Header: tmproto.Header{Height: 1}})
app.BeginBlock(abci.RequestBeginBlock{Header: tmprototypes.Header{Height: 1}})
app.Commit()
app.BeginBlock(abci.RequestBeginBlock{Header: tmproto.Header{Height: 2}})
app.BeginBlock(abci.RequestBeginBlock{Header: tmprototypes.Header{Height: 2}})
app.Commit()
testCases := []struct {
+12 -14
View File
@@ -2,7 +2,6 @@ package baseapp
import (
"context"
"errors"
"fmt"
abci "github.com/tendermint/tendermint/abci/types"
@@ -62,9 +61,7 @@ type BaseApp struct { // nolint: maligned
fauxMerkleMode bool // if true, IAVL MountStores uses MountStoresDB for simulation speed.
// manages snapshots, i.e. dumps of app state at certain intervals
snapshotManager *snapshots.Manager
snapshotInterval uint64 // block interval between state sync snapshots
snapshotKeepRecent uint32 // recent state sync snapshots to keep
snapshotManager *snapshots.Manager
// volatile states:
//
@@ -252,7 +249,7 @@ func (app *BaseApp) LoadLatestVersion() error {
return fmt.Errorf("failed to load latest version: %w", err)
}
return app.init()
return app.Init()
}
// DefaultStoreLoader will be used by default and loads the latest version
@@ -284,7 +281,7 @@ func (app *BaseApp) LoadVersion(version int64) error {
return fmt.Errorf("failed to load version %d: %w", version, err)
}
return app.init()
return app.Init()
}
// LastCommitID returns the last CommitID of the multistore.
@@ -297,7 +294,11 @@ func (app *BaseApp) LastBlockHeight() int64 {
return app.cms.LastCommitID().Version
}
func (app *BaseApp) init() error {
// Init initializes the app. It seals the app, preventing any
// further modifications. In addition, it validates the app against
// the earlier provided settings. Returns an error if validation fails.
// nil otherwise. Panics if the app is already sealed.
func (app *BaseApp) Init() error {
if app.sealed {
panic("cannot call initFromMainStore: baseapp already sealed")
}
@@ -306,14 +307,11 @@ func (app *BaseApp) init() error {
app.setCheckState(tmproto.Header{})
app.Seal()
// make sure the snapshot interval is a multiple of the pruning KeepEvery interval
if app.snapshotManager != nil && app.snapshotInterval > 0 {
if _, ok := app.cms.(*rootmulti.Store); !ok {
return errors.New("state sync snapshots require a rootmulti store")
}
rms, ok := app.cms.(*rootmulti.Store)
if !ok {
return fmt.Errorf("invalid commit multi-store; expected %T, got: %T", &rootmulti.Store{}, app.cms)
}
return nil
return rms.GetPruning().Validate()
}
func (app *BaseApp) setMinGasPrices(gasPrices sdk.DecCoins) {
+425 -76
View File
@@ -8,16 +8,11 @@ import (
"fmt"
"math"
"math/rand"
"os"
"strings"
"sync"
"testing"
"time"
"google.golang.org/protobuf/proto"
"github.com/cosmos/cosmos-sdk/testutil/testdata_pulsar"
"github.com/gogo/protobuf/jsonpb"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -25,17 +20,21 @@ import (
"github.com/tendermint/tendermint/libs/log"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
dbm "github.com/tendermint/tm-db"
"google.golang.org/protobuf/proto"
"github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/codec/legacy"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
pruningtypes "github.com/cosmos/cosmos-sdk/pruning/types"
"github.com/cosmos/cosmos-sdk/simapp"
"github.com/cosmos/cosmos-sdk/snapshots"
snapshottypes "github.com/cosmos/cosmos-sdk/snapshots/types"
"github.com/cosmos/cosmos-sdk/store/rootmulti"
storetypes "github.com/cosmos/cosmos-sdk/store/types"
"github.com/cosmos/cosmos-sdk/testutil"
"github.com/cosmos/cosmos-sdk/testutil/testdata"
"github.com/cosmos/cosmos-sdk/testutil/testdata_pulsar"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/cosmos/cosmos-sdk/types/tx"
@@ -58,6 +57,14 @@ type paramStore struct {
db *dbm.MemDB
}
type setupConfig struct {
blocks uint64
blockTxs int
snapshotInterval uint64
snapshotKeepRecent uint32
pruningOpts pruningtypes.PruningOptions
}
func (ps *paramStore) Set(_ sdk.Context, key []byte, value interface{}) {
bz, err := json.Marshal(value)
if err != nil {
@@ -121,7 +128,7 @@ func aminoTxEncoder(cdc *codec.LegacyAmino) sdk.TxEncoder {
}
// simple one store baseapp
func setupBaseApp(t *testing.T, options ...func(*baseapp.BaseApp)) *baseapp.BaseApp {
func setupBaseApp(t *testing.T, options ...func(*baseapp.BaseApp)) (*baseapp.BaseApp, error) {
app := newBaseApp(t.Name(), options...)
require.Equal(t, t.Name(), app.Name())
@@ -130,8 +137,7 @@ func setupBaseApp(t *testing.T, options ...func(*baseapp.BaseApp)) *baseapp.Base
// stores are mounted
err := app.LoadLatestVersion()
require.Nil(t, err)
return app
return app, err
}
// testTxHandler is a tx.Handler used for the mock app, it does not
@@ -150,7 +156,7 @@ func testTxHandler(options middleware.TxHandlerOptions, customTxHandlerMiddlewar
}
// simple one store baseapp with data and snapshots. Each tx is 1 MB in size (uncompressed).
func setupBaseAppWithSnapshots(t *testing.T, blocks uint, blockTxs int, options ...func(*baseapp.BaseApp)) (*baseapp.BaseApp, func()) {
func setupBaseAppWithSnapshots(t *testing.T, config *setupConfig) (*baseapp.BaseApp, error) {
codec := codec.NewLegacyAmino()
registerTestCodec(codec)
routerOpt := func(bapp *baseapp.BaseApp) {
@@ -178,28 +184,22 @@ func setupBaseAppWithSnapshots(t *testing.T, blocks uint, blockTxs int, options
bapp.SetTxHandler(txHandler)
}
snapshotInterval := uint64(2)
snapshotTimeout := 1 * time.Minute
snapshotDir, err := os.MkdirTemp("", "baseapp")
snapshotStore, err := snapshots.NewStore(dbm.NewMemDB(), testutil.GetTempDir(t))
require.NoError(t, err)
snapshotStore, err := snapshots.NewStore(dbm.NewMemDB(), snapshotDir)
require.NoError(t, err)
teardown := func() {
_ = os.RemoveAll(snapshotDir)
}
app := setupBaseApp(t, append(options,
baseapp.SetSnapshotStore(snapshotStore),
baseapp.SetSnapshotInterval(snapshotInterval),
routerOpt)...)
app, err := setupBaseApp(t, routerOpt, baseapp.SetSnapshot(snapshotStore, snapshottypes.NewSnapshotOptions(config.snapshotInterval, uint32(config.snapshotKeepRecent))), baseapp.SetPruning(config.pruningOpts))
if err != nil {
return nil, err
}
app.InitChain(abci.RequestInitChain{})
r := rand.New(rand.NewSource(3920758213583))
keyCounter := 0
for height := int64(1); height <= int64(blocks); height++ {
for height := int64(1); height <= int64(config.blocks); height++ {
app.BeginBlock(abci.RequestBeginBlock{Header: tmproto.Header{Height: height}})
for txNum := 0; txNum < blockTxs; txNum++ {
for txNum := 0; txNum < config.blockTxs; txNum++ {
tx := txTest{Msgs: []sdk.Msg{}}
for msgNum := 0; msgNum < 100; msgNum++ {
key := []byte(fmt.Sprintf("%v", keyCounter))
@@ -218,7 +218,7 @@ func setupBaseAppWithSnapshots(t *testing.T, blocks uint, blockTxs int, options
app.Commit()
// Wait for snapshot to be taken, since it happens asynchronously.
if uint64(height)%snapshotInterval == 0 {
if config.snapshotInterval > 0 && uint64(height)%config.snapshotInterval == 0 {
start := time.Now()
for {
if time.Since(start) > snapshotTimeout {
@@ -234,11 +234,12 @@ func setupBaseAppWithSnapshots(t *testing.T, blocks uint, blockTxs int, options
}
}
return app, teardown
return app, nil
}
func TestMountStores(t *testing.T) {
app := setupBaseApp(t)
app, err := setupBaseApp(t)
require.NoError(t, err)
// check both stores
store1 := app.CMS().GetCommitKVStore(capKey1)
@@ -270,7 +271,7 @@ func (th MockTxHandler) SimulateTx(goCtx context.Context, req tx.Request) (tx.Re
}
func TestConsensusParamsNotNil(t *testing.T) {
app := setupBaseApp(t, func(app *baseapp.BaseApp) {
app, err := setupBaseApp(t, func(app *baseapp.BaseApp) {
app.SetBeginBlocker(func(ctx sdk.Context, req abci.RequestBeginBlock) abci.ResponseBeginBlock {
require.NotNil(t, ctx.ConsensusParams())
return abci.ResponseBeginBlock{}
@@ -283,13 +284,14 @@ func TestConsensusParamsNotNil(t *testing.T) {
}, func(app *baseapp.BaseApp) {
app.SetTxHandler(MockTxHandler{T: t})
})
require.NoError(t, err)
header := tmproto.Header{Height: 1}
app.BeginBlock(abci.RequestBeginBlock{Header: header})
app.EndBlock(abci.RequestEndBlock{Height: header.Height})
app.CheckTx(abci.RequestCheckTx{})
app.DeliverTx(abci.RequestDeliverTx{})
_, _, err := app.Simulate([]byte{})
_, _, err = app.Simulate([]byte{})
require.NoError(t, err)
}
@@ -297,7 +299,7 @@ func TestConsensusParamsNotNil(t *testing.T) {
// Test that LoadLatestVersion actually does.
func TestLoadVersion(t *testing.T) {
logger := defaultLogger()
pruningOpt := baseapp.SetPruning(storetypes.PruneNothing)
pruningOpt := baseapp.SetPruning(pruningtypes.NewPruningOptions(pruningtypes.PruningNothing))
db := dbm.NewMemDB()
name := t.Name()
app := baseapp.NewBaseApp(name, logger, db, pruningOpt)
@@ -349,8 +351,8 @@ func useDefaultLoader(app *baseapp.BaseApp) {
}
func initStore(t *testing.T, db dbm.DB, storeKey string, k, v []byte) {
rs := rootmulti.NewStore(db)
rs.SetPruning(storetypes.PruneNothing)
rs := rootmulti.NewStore(db, log.NewNopLogger())
rs.SetPruning(pruningtypes.NewPruningOptions(pruningtypes.PruningNothing))
key := sdk.NewKVStoreKey(storeKey)
rs.MountStoreWithDB(key, storetypes.StoreTypeIAVL, nil)
err := rs.LoadLatestVersion()
@@ -366,8 +368,8 @@ func initStore(t *testing.T, db dbm.DB, storeKey string, k, v []byte) {
}
func checkStore(t *testing.T, db dbm.DB, ver int64, storeKey string, k, v []byte) {
rs := rootmulti.NewStore(db)
rs.SetPruning(storetypes.PruneDefault)
rs := rootmulti.NewStore(db, log.NewNopLogger())
rs.SetPruning(pruningtypes.NewPruningOptions(pruningtypes.PruningDefault))
key := sdk.NewKVStoreKey(storeKey)
rs.MountStoreWithDB(key, storetypes.StoreTypeIAVL, nil)
err := rs.LoadLatestVersion()
@@ -410,7 +412,7 @@ func TestSetLoader(t *testing.T) {
initStore(t, db, tc.origStoreKey, k, v)
// load the app with the existing db
opts := []func(*baseapp.BaseApp){baseapp.SetPruning(storetypes.PruneNothing)}
opts := []func(*baseapp.BaseApp){baseapp.SetPruning(pruningtypes.NewPruningOptions(pruningtypes.PruningNothing))}
if tc.setLoader != nil {
opts = append(opts, tc.setLoader)
}
@@ -433,7 +435,7 @@ func TestSetLoader(t *testing.T) {
func TestVersionSetterGetter(t *testing.T) {
logger := defaultLogger()
pruningOpt := baseapp.SetPruning(storetypes.PruneDefault)
pruningOpt := baseapp.SetPruning(pruningtypes.NewPruningOptions(pruningtypes.PruningDefault))
db := dbm.NewMemDB()
name := t.Name()
app := baseapp.NewBaseApp(name, logger, db, pruningOpt)
@@ -453,7 +455,7 @@ func TestVersionSetterGetter(t *testing.T) {
func TestLoadVersionInvalid(t *testing.T) {
logger := log.NewNopLogger()
pruningOpt := baseapp.SetPruning(storetypes.PruneNothing)
pruningOpt := baseapp.SetPruning(pruningtypes.NewPruningOptions(pruningtypes.PruningNothing))
db := dbm.NewMemDB()
name := t.Name()
app := baseapp.NewBaseApp(name, logger, db, pruningOpt)
@@ -485,20 +487,22 @@ func TestLoadVersionInvalid(t *testing.T) {
func TestLoadVersionPruning(t *testing.T) {
logger := log.NewNopLogger()
pruningOptions := storetypes.PruningOptions{
KeepRecent: 2,
Interval: 1,
}
pruningOptions := pruningtypes.NewCustomPruningOptions(10, 15)
pruningOpt := baseapp.SetPruning(pruningOptions)
db := dbm.NewMemDB()
name := t.Name()
app := baseapp.NewBaseApp(name, logger, db, pruningOpt)
snapshotStore, err := snapshots.NewStore(dbm.NewMemDB(), testutil.GetTempDir(t))
require.NoError(t, err)
snapshotOpt := baseapp.SetSnapshot(snapshotStore, snapshottypes.NewSnapshotOptions(3, 1))
app := baseapp.NewBaseApp(name, logger, db, pruningOpt, snapshotOpt)
// make a cap key and mount the store
capKey := sdk.NewKVStoreKey("key1")
app.MountStores(capKey)
err := app.LoadLatestVersion() // needed to make stores non-nil
err = app.LoadLatestVersion() // needed to make stores non-nil
require.Nil(t, err)
emptyCommitID := storetypes.CommitID{}
@@ -511,31 +515,31 @@ func TestLoadVersionPruning(t *testing.T) {
var lastCommitID storetypes.CommitID
// Commit seven blocks, of which 7 (latest) is kept in addition to 6, 5
// (keep recent) and 3 (keep every).
for i := int64(1); i <= 7; i++ {
// Commit 15 blocks, of which 15 (latest) is kept in addition to 5-14 inclusive
// (keep recent) and 3 (snapshot-interval).
for i := int64(1); i <= 15; i++ {
app.BeginBlock(abci.RequestBeginBlock{Header: tmproto.Header{Height: i}})
res := app.Commit()
lastCommitID = storetypes.CommitID{Version: i, Hash: res.Data}
}
for _, v := range []int64{1, 2, 4} {
for _, v := range []int64{1, 2, 3, 4} {
_, err = app.CMS().CacheMultiStoreWithVersion(v)
require.NoError(t, err)
}
for _, v := range []int64{3, 5, 6, 7} {
for _, v := range []int64{3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14} {
_, err = app.CMS().CacheMultiStoreWithVersion(v)
require.NoError(t, err)
}
// reload with LoadLatestVersion, check it loads last version
app = baseapp.NewBaseApp(name, logger, db, pruningOpt)
app = baseapp.NewBaseApp(name, logger, db, pruningOpt, snapshotOpt)
app.MountStores(capKey)
err = app.LoadLatestVersion()
require.Nil(t, err)
testLoadVersionHelper(t, app, int64(7), lastCommitID)
testLoadVersionHelper(t, app, int64(15), lastCommitID)
}
func testLoadVersionHelper(t *testing.T, app *baseapp.BaseApp, expectedHeight int64, expectedID storetypes.CommitID) {
@@ -577,7 +581,8 @@ func TestInfo(t *testing.T) {
}
func TestBaseAppOptionSeal(t *testing.T) {
app := setupBaseApp(t)
app, err := setupBaseApp(t)
require.NoError(t, err)
require.Panics(t, func() {
app.SetName("")
@@ -1018,7 +1023,8 @@ func TestCheckTx(t *testing.T) {
bapp.SetTxHandler(txHandler)
}
app := setupBaseApp(t, txHandlerOpt)
app, err := setupBaseApp(t, txHandlerOpt)
require.NoError(t, err)
nTxs := int64(5)
app.InitChain(abci.RequestInitChain{})
@@ -1075,7 +1081,9 @@ func TestDeliverTx(t *testing.T) {
)
bapp.SetTxHandler(txHandler)
}
app := setupBaseApp(t, txHandlerOpt)
app, err := setupBaseApp(t, txHandlerOpt)
require.NoError(t, err)
app.InitChain(abci.RequestInitChain{})
nBlocks := 3
@@ -1135,7 +1143,9 @@ func TestMultiMsgDeliverTx(t *testing.T) {
)
bapp.SetTxHandler(txHandler)
}
app := setupBaseApp(t, txHandlerOpt)
app, err := setupBaseApp(t, txHandlerOpt)
require.NoError(t, err)
// run a multi-msg tx
// with all msgs the same route
@@ -1220,7 +1230,8 @@ func TestSimulateTx(t *testing.T) {
)
bapp.SetTxHandler(txHandler)
}
app := setupBaseApp(t, txHandlerOpt)
app, err := setupBaseApp(t, txHandlerOpt)
require.NoError(t, err)
app.InitChain(abci.RequestInitChain{})
@@ -1294,7 +1305,8 @@ func TestRunInvalidTransaction(t *testing.T) {
)
bapp.SetTxHandler(txHandler)
}
app := setupBaseApp(t, txHandlerOpt)
app, err := setupBaseApp(t, txHandlerOpt)
require.NoError(t, err)
header := tmproto.Header{Height: 1}
app.BeginBlock(abci.RequestBeginBlock{Header: header})
@@ -1420,7 +1432,8 @@ func TestTxGasLimits(t *testing.T) {
bapp.SetTxHandler(txHandler)
}
app := setupBaseApp(t, txHandlerOpt)
app, err := setupBaseApp(t, txHandlerOpt)
require.NoError(t, err)
header := tmproto.Header{Height: 1}
app.BeginBlock(abci.RequestBeginBlock{Header: header})
@@ -1507,8 +1520,8 @@ func TestMaxBlockGasLimits(t *testing.T) {
)
bapp.SetTxHandler(txHandler)
}
app := setupBaseApp(t, txHandlerOpt)
app, err := setupBaseApp(t, txHandlerOpt)
require.NoError(t, err)
app.InitChain(abci.RequestInitChain{
ConsensusParams: &tmproto.ConsensusParams{
Block: &tmproto.BlockParams{
@@ -1593,7 +1606,8 @@ func TestBaseAppMiddleware(t *testing.T) {
)
bapp.SetTxHandler(txHandler)
}
app := setupBaseApp(t, txHandlerOpt)
app, err := setupBaseApp(t, txHandlerOpt)
require.NoError(t, err)
app.InitChain(abci.RequestInitChain{})
@@ -1684,8 +1698,8 @@ func TestGasConsumptionBadTx(t *testing.T) {
)
bapp.SetTxHandler(txHandler)
}
app := setupBaseApp(t, txHandlerOpt)
app, err := setupBaseApp(t, txHandlerOpt)
require.NoError(t, err)
app.InitChain(abci.RequestInitChain{
ConsensusParams: &tmproto.ConsensusParams{
Block: &tmproto.BlockParams{
@@ -1750,7 +1764,8 @@ func TestQuery(t *testing.T) {
)
bapp.SetTxHandler(txHandler)
}
app := setupBaseApp(t, txHandlerOpt)
app, err := setupBaseApp(t, txHandlerOpt)
require.NoError(t, err)
app.InitChain(abci.RequestInitChain{})
@@ -1798,7 +1813,8 @@ func TestGRPCQuery(t *testing.T) {
)
}
app := setupBaseApp(t, grpcQueryOpt)
app, err := setupBaseApp(t, grpcQueryOpt)
require.NoError(t, err)
app.GRPCQueryRouter().SetInterfaceRegistry(codectypes.NewInterfaceRegistry())
app.InitChain(abci.RequestInitChain{})
@@ -1833,7 +1849,8 @@ func TestGRPCQueryPulsar(t *testing.T) {
)
}
app := setupBaseApp(t, grpcQueryOpt)
app, err := setupBaseApp(t, grpcQueryOpt)
require.NoError(t, err)
app.GRPCQueryRouter().SetInterfaceRegistry(codectypes.NewInterfaceRegistry())
app.InitChain(abci.RequestInitChain{})
@@ -1876,7 +1893,8 @@ func TestP2PQuery(t *testing.T) {
})
}
app := setupBaseApp(t, addrPeerFilterOpt, idPeerFilterOpt)
app, err := setupBaseApp(t, addrPeerFilterOpt, idPeerFilterOpt)
require.NoError(t, err)
addrQuery := abci.RequestQuery{
Path: "/p2p/filter/addr/1.1.1.1:8000",
@@ -1892,7 +1910,8 @@ func TestP2PQuery(t *testing.T) {
}
func TestGetMaximumBlockGas(t *testing.T) {
app := setupBaseApp(t)
app, err := setupBaseApp(t)
require.NoError(t, err)
app.InitChain(abci.RequestInitChain{})
ctx := app.NewContext(true, tmproto.Header{})
@@ -1910,8 +1929,16 @@ func TestGetMaximumBlockGas(t *testing.T) {
}
func TestListSnapshots(t *testing.T) {
app, teardown := setupBaseAppWithSnapshots(t, 5, 4)
defer teardown()
setupConfig := &setupConfig{
blocks: 5,
blockTxs: 4,
snapshotInterval: 2,
snapshotKeepRecent: 2,
pruningOpts: pruningtypes.NewPruningOptions(pruningtypes.PruningNothing),
}
app, err := setupBaseAppWithSnapshots(t, setupConfig)
require.NoError(t, err)
resp := app.ListSnapshots(abci.RequestListSnapshots{})
for _, s := range resp.Snapshots {
@@ -1926,9 +1953,148 @@ func TestListSnapshots(t *testing.T) {
}}, resp)
}
func TestSnapshotWithPruning(t *testing.T) {
testcases := map[string]struct {
config *setupConfig
expectedSnapshots []*abci.Snapshot
expectedErr error
}{
"prune nothing with snapshot": {
config: &setupConfig{
blocks: 20,
blockTxs: 2,
snapshotInterval: 5,
snapshotKeepRecent: 1,
pruningOpts: pruningtypes.NewPruningOptions(pruningtypes.PruningNothing),
},
expectedSnapshots: []*abci.Snapshot{
{Height: 20, Format: 2, Chunks: 5},
},
},
"prune everything with snapshot": {
config: &setupConfig{
blocks: 20,
blockTxs: 2,
snapshotInterval: 5,
snapshotKeepRecent: 1,
pruningOpts: pruningtypes.NewPruningOptions(pruningtypes.PruningEverything),
},
expectedSnapshots: []*abci.Snapshot{
{Height: 20, Format: 2, Chunks: 5},
},
},
"default pruning with snapshot": {
config: &setupConfig{
blocks: 20,
blockTxs: 2,
snapshotInterval: 5,
snapshotKeepRecent: 1,
pruningOpts: pruningtypes.NewPruningOptions(pruningtypes.PruningDefault),
},
expectedSnapshots: []*abci.Snapshot{
{Height: 20, Format: 2, Chunks: 5},
},
},
"custom": {
config: &setupConfig{
blocks: 25,
blockTxs: 2,
snapshotInterval: 5,
snapshotKeepRecent: 2,
pruningOpts: pruningtypes.NewCustomPruningOptions(12, 12),
},
expectedSnapshots: []*abci.Snapshot{
{Height: 25, Format: 2, Chunks: 6},
{Height: 20, Format: 2, Chunks: 5},
},
},
"no snapshots": {
config: &setupConfig{
blocks: 10,
blockTxs: 2,
snapshotInterval: 0, // 0 implies disable snapshots
pruningOpts: pruningtypes.NewPruningOptions(pruningtypes.PruningNothing),
},
expectedSnapshots: []*abci.Snapshot{},
},
"keep all snapshots": {
config: &setupConfig{
blocks: 10,
blockTxs: 2,
snapshotInterval: 3,
snapshotKeepRecent: 0, // 0 implies keep all snapshots
pruningOpts: pruningtypes.NewPruningOptions(pruningtypes.PruningNothing),
},
expectedSnapshots: []*abci.Snapshot{
{Height: 9, Format: 2, Chunks: 2},
{Height: 6, Format: 2, Chunks: 2},
{Height: 3, Format: 2, Chunks: 1},
},
},
}
for name, tc := range testcases {
t.Run(name, func(t *testing.T) {
app, err := setupBaseAppWithSnapshots(t, tc.config)
if tc.expectedErr != nil {
require.Error(t, err)
require.Equal(t, tc.expectedErr.Error(), err.Error())
return
}
require.NoError(t, err)
resp := app.ListSnapshots(abci.RequestListSnapshots{})
for _, s := range resp.Snapshots {
assert.NotEmpty(t, s.Hash)
assert.NotEmpty(t, s.Metadata)
s.Hash = nil
s.Metadata = nil
}
fmt.Println(resp)
assert.Equal(t, abci.ResponseListSnapshots{Snapshots: tc.expectedSnapshots}, resp)
// Validate that heights were pruned correctly by querying the state at the last height that should be present relative to latest
// and the first height that should be pruned.
//
// Exceptions:
// * Prune nothing: should be able to query all heights (we only test first and latest)
// * Prune default: should be able to query all heights (we only test first and latest)
// * The reason for default behaving this way is that we only commit 20 heights but default has 100_000 keep-recent
var lastExistingHeight int64
if tc.config.pruningOpts.GetPruningStrategy() == pruningtypes.PruningNothing || tc.config.pruningOpts.GetPruningStrategy() == pruningtypes.PruningDefault {
lastExistingHeight = 1
} else {
// Integer division rounds down so by multiplying back we get the last height at which we pruned
lastExistingHeight = int64((tc.config.blocks/tc.config.pruningOpts.Interval)*tc.config.pruningOpts.Interval - tc.config.pruningOpts.KeepRecent)
}
// Query 1
res := app.Query(abci.RequestQuery{Path: fmt.Sprintf("/store/%s/key", capKey2.Name()), Data: []byte("0"), Height: lastExistingHeight})
require.NotNil(t, res, "height: %d", lastExistingHeight)
require.NotNil(t, res.Value, "height: %d", lastExistingHeight)
// Query 2
res = app.Query(abci.RequestQuery{Path: fmt.Sprintf("/store/%s/key", capKey2.Name()), Data: []byte("0"), Height: lastExistingHeight - 1})
require.NotNil(t, res, "height: %d", lastExistingHeight-1)
if tc.config.pruningOpts.GetPruningStrategy() == pruningtypes.PruningNothing || tc.config.pruningOpts.GetPruningStrategy() == pruningtypes.PruningDefault {
// With prune nothing or default, we query height 0 which translates to the latest height.
require.NotNil(t, res.Value, "height: %d", lastExistingHeight-1)
}
})
}
}
func TestLoadSnapshotChunk(t *testing.T) {
app, teardown := setupBaseAppWithSnapshots(t, 2, 5)
defer teardown()
setupConfig := &setupConfig{
blocks: 2,
blockTxs: 5,
snapshotInterval: 2,
snapshotKeepRecent: 2,
pruningOpts: pruningtypes.NewPruningOptions(pruningtypes.PruningNothing),
}
app, err := setupBaseAppWithSnapshots(t, setupConfig)
require.NoError(t, err)
testcases := map[string]struct {
height uint64
@@ -1963,8 +2129,15 @@ func TestLoadSnapshotChunk(t *testing.T) {
func TestOfferSnapshot_Errors(t *testing.T) {
// Set up app before test cases, since it's fairly expensive.
app, teardown := setupBaseAppWithSnapshots(t, 0, 0)
defer teardown()
setupConfig := &setupConfig{
blocks: 0,
blockTxs: 0,
snapshotInterval: 2,
snapshotKeepRecent: 2,
pruningOpts: pruningtypes.NewPruningOptions(pruningtypes.PruningNothing),
}
app, err := setupBaseAppWithSnapshots(t, setupConfig)
require.NoError(t, err)
m := snapshottypes.Metadata{ChunkHashes: [][]byte{{1}, {2}, {3}}}
metadata, err := m.Marshal()
@@ -2018,11 +2191,25 @@ func TestOfferSnapshot_Errors(t *testing.T) {
}
func TestApplySnapshotChunk(t *testing.T) {
source, teardown := setupBaseAppWithSnapshots(t, 4, 10)
defer teardown()
setupConfig1 := &setupConfig{
blocks: 4,
blockTxs: 10,
snapshotInterval: 2,
snapshotKeepRecent: 2,
pruningOpts: pruningtypes.NewPruningOptions(pruningtypes.PruningNothing),
}
source, err := setupBaseAppWithSnapshots(t, setupConfig1)
require.NoError(t, err)
target, teardown := setupBaseAppWithSnapshots(t, 0, 0)
defer teardown()
setupConfig2 := &setupConfig{
blocks: 0,
blockTxs: 0,
snapshotInterval: 2,
snapshotKeepRecent: 2,
pruningOpts: pruningtypes.NewPruningOptions(pruningtypes.PruningNothing),
}
target, err := setupBaseAppWithSnapshots(t, setupConfig2)
require.NoError(t, err)
// Fetch latest snapshot to restore
respList := source.ListSnapshots(abci.RequestListSnapshots{})
@@ -2102,7 +2289,8 @@ func TestWithRouter(t *testing.T) {
)
bapp.SetTxHandler(txHandler)
}
app := setupBaseApp(t, txHandlerOpt)
app, err := setupBaseApp(t, txHandlerOpt)
require.NoError(t, err)
app.InitChain(abci.RequestInitChain{})
nBlocks := 3
@@ -2159,3 +2347,164 @@ func TestBaseApp_EndBlock(t *testing.T) {
require.Equal(t, int64(100), res.GetValidatorUpdates()[0].Power)
require.Equal(t, cp.Block.MaxGas, res.ConsensusParamUpdates.Block.MaxGas)
}
func TestBaseApp_Init(t *testing.T) {
db := dbm.NewMemDB()
name := t.Name()
logger := defaultLogger()
snapshotStore, err := snapshots.NewStore(dbm.NewMemDB(), testutil.GetTempDir(t))
require.NoError(t, err)
testCases := map[string]struct {
bapp *baseapp.BaseApp
expectedPruning pruningtypes.PruningOptions
expectedSnapshot snapshottypes.SnapshotOptions
expectedErr error
}{
"snapshot but no pruning": {
baseapp.NewBaseApp(name, logger, db,
baseapp.SetSnapshot(snapshotStore, snapshottypes.NewSnapshotOptions(1500, 2)),
),
pruningtypes.NewPruningOptions(pruningtypes.PruningNothing),
snapshottypes.NewSnapshotOptions(1500, 2),
// if no pruning is set, the default is PruneNothing
nil,
},
"pruning everything only": {
baseapp.NewBaseApp(name, logger, db,
baseapp.SetPruning(pruningtypes.NewPruningOptions(pruningtypes.PruningEverything)),
),
pruningtypes.NewPruningOptions(pruningtypes.PruningEverything),
snapshottypes.NewSnapshotOptions(snapshottypes.SnapshotIntervalOff, 0),
nil,
},
"pruning nothing only": {
baseapp.NewBaseApp(name, logger, db,
baseapp.SetPruning(pruningtypes.NewPruningOptions(pruningtypes.PruningNothing)),
),
pruningtypes.NewPruningOptions(pruningtypes.PruningNothing),
snapshottypes.NewSnapshotOptions(snapshottypes.SnapshotIntervalOff, 0),
nil,
},
"pruning default only": {
baseapp.NewBaseApp(name, logger, db,
baseapp.SetPruning(pruningtypes.NewPruningOptions(pruningtypes.PruningDefault)),
),
pruningtypes.NewPruningOptions(pruningtypes.PruningDefault),
snapshottypes.NewSnapshotOptions(snapshottypes.SnapshotIntervalOff, 0),
nil,
},
"pruning custom only": {
baseapp.NewBaseApp(name, logger, db,
baseapp.SetPruning(pruningtypes.NewCustomPruningOptions(10, 10)),
),
pruningtypes.NewCustomPruningOptions(10, 10),
snapshottypes.NewSnapshotOptions(snapshottypes.SnapshotIntervalOff, 0),
nil,
},
"pruning everything and snapshots": {
baseapp.NewBaseApp(name, logger, db,
baseapp.SetPruning(pruningtypes.NewPruningOptions(pruningtypes.PruningEverything)),
baseapp.SetSnapshot(snapshotStore, snapshottypes.NewSnapshotOptions(1500, 2)),
),
pruningtypes.NewPruningOptions(pruningtypes.PruningEverything),
snapshottypes.NewSnapshotOptions(1500, 2),
nil,
},
"pruning nothing and snapshots": {
baseapp.NewBaseApp(name, logger, db,
baseapp.SetPruning(pruningtypes.NewPruningOptions(pruningtypes.PruningNothing)),
baseapp.SetSnapshot(snapshotStore, snapshottypes.NewSnapshotOptions(1500, 2)),
),
pruningtypes.NewPruningOptions(pruningtypes.PruningNothing),
snapshottypes.NewSnapshotOptions(1500, 2),
nil,
},
"pruning default and snapshots": {
baseapp.NewBaseApp(name, logger, db,
baseapp.SetPruning(pruningtypes.NewPruningOptions(pruningtypes.PruningDefault)),
baseapp.SetSnapshot(snapshotStore, snapshottypes.NewSnapshotOptions(1500, 2)),
),
pruningtypes.NewPruningOptions(pruningtypes.PruningDefault),
snapshottypes.NewSnapshotOptions(1500, 2),
nil,
},
"pruning custom and snapshots": {
baseapp.NewBaseApp(name, logger, db,
baseapp.SetPruning(pruningtypes.NewCustomPruningOptions(10, 10)),
baseapp.SetSnapshot(snapshotStore, snapshottypes.NewSnapshotOptions(1500, 2)),
),
pruningtypes.NewCustomPruningOptions(10, 10),
snapshottypes.NewSnapshotOptions(1500, 2),
nil,
},
"error custom pruning 0 interval": {
baseapp.NewBaseApp(name, logger, db,
baseapp.SetPruning(pruningtypes.NewCustomPruningOptions(10, 0)),
baseapp.SetSnapshot(snapshotStore, snapshottypes.NewSnapshotOptions(1500, 2)),
),
pruningtypes.NewCustomPruningOptions(10, 0),
snapshottypes.NewSnapshotOptions(1500, 2),
pruningtypes.ErrPruningIntervalZero,
},
"error custom pruning too small interval": {
baseapp.NewBaseApp(name, logger, db,
baseapp.SetPruning(pruningtypes.NewCustomPruningOptions(10, 9)),
baseapp.SetSnapshot(snapshotStore, snapshottypes.NewSnapshotOptions(1500, 2)),
),
pruningtypes.NewCustomPruningOptions(10, 9),
snapshottypes.NewSnapshotOptions(1500, 2),
pruningtypes.ErrPruningIntervalTooSmall,
},
"error custom pruning too small keep recent": {
baseapp.NewBaseApp(name, logger, db,
baseapp.SetPruning(pruningtypes.NewCustomPruningOptions(1, 10)),
baseapp.SetSnapshot(snapshotStore, snapshottypes.NewSnapshotOptions(1500, 2)),
),
pruningtypes.NewCustomPruningOptions(9, 10),
snapshottypes.NewSnapshotOptions(1500, 2),
pruningtypes.ErrPruningKeepRecentTooSmall,
},
"snapshot zero interval - manager not set": {
baseapp.NewBaseApp(name, logger, db,
baseapp.SetPruning(pruningtypes.NewCustomPruningOptions(10, 10)),
baseapp.SetSnapshot(snapshotStore, snapshottypes.NewSnapshotOptions(snapshottypes.SnapshotIntervalOff, 2)),
),
pruningtypes.NewCustomPruningOptions(10, 10),
snapshottypes.NewSnapshotOptions(snapshottypes.SnapshotIntervalOff, 0),
nil,
},
"snapshot zero keep recent - allowed": {
baseapp.NewBaseApp(name, logger, db,
baseapp.SetPruning(pruningtypes.NewCustomPruningOptions(10, 10)),
baseapp.SetSnapshot(snapshotStore, snapshottypes.NewSnapshotOptions(1500, 0)),
),
pruningtypes.NewCustomPruningOptions(10, 10),
snapshottypes.NewSnapshotOptions(1500, 0), // 0 snapshot-keep-recent means keep all
nil,
},
}
for _, tc := range testCases {
// Init and validate
require.Equal(t, tc.expectedErr, tc.bapp.Init())
if tc.expectedErr != nil {
continue
}
// Check that settings were set correctly
actualPruning := tc.bapp.CMS().GetPruning()
require.Equal(t, tc.expectedPruning, actualPruning)
snapshotManager := tc.bapp.GetSnapshotManager()
if tc.expectedSnapshot.Interval == snapshottypes.SnapshotIntervalOff {
require.Nil(t, snapshotManager)
continue
}
require.NotNil(t, snapshotManager)
require.Equal(t, tc.expectedSnapshot.Interval, snapshotManager.GetInterval())
require.Equal(t, tc.expectedSnapshot.KeepRecent, snapshotManager.GetKeepRecent())
}
}
+12 -35
View File
@@ -7,7 +7,9 @@ import (
dbm "github.com/tendermint/tm-db"
"github.com/cosmos/cosmos-sdk/codec/types"
pruningtypes "github.com/cosmos/cosmos-sdk/pruning/types"
"github.com/cosmos/cosmos-sdk/snapshots"
snapshottypes "github.com/cosmos/cosmos-sdk/snapshots/types"
"github.com/cosmos/cosmos-sdk/store"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/tx"
@@ -17,7 +19,7 @@ import (
// for options that need access to non-exported fields of the BaseApp
// SetPruning sets a pruning option on the multistore associated with the app
func SetPruning(opts sdk.PruningOptions) func(*BaseApp) {
func SetPruning(opts pruningtypes.PruningOptions) func(*BaseApp) {
return func(bapp *BaseApp) { bapp.cms.SetPruning(opts) }
}
@@ -69,19 +71,9 @@ func SetInterBlockCache(cache sdk.MultiStorePersistentCache) func(*BaseApp) {
return func(app *BaseApp) { app.setInterBlockCache(cache) }
}
// SetSnapshotInterval sets the snapshot interval.
func SetSnapshotInterval(interval uint64) func(*BaseApp) {
return func(app *BaseApp) { app.SetSnapshotInterval(interval) }
}
// SetSnapshotKeepRecent sets the recent snapshots to keep.
func SetSnapshotKeepRecent(keepRecent uint32) func(*BaseApp) {
return func(app *BaseApp) { app.SetSnapshotKeepRecent(keepRecent) }
}
// SetSnapshotStore sets the snapshot store.
func SetSnapshotStore(snapshotStore *snapshots.Store) func(*BaseApp) {
return func(app *BaseApp) { app.SetSnapshotStore(snapshotStore) }
// SetSnapshot sets the snapshot store.
func SetSnapshot(snapshotStore *snapshots.Store, opts snapshottypes.SnapshotOptions) func(*BaseApp) {
return func(app *BaseApp) { app.SetSnapshot(snapshotStore, opts) }
}
func (app *BaseApp) SetName(name string) {
@@ -201,32 +193,17 @@ func (app *BaseApp) SetStoreLoader(loader StoreLoader) {
app.storeLoader = loader
}
// SetSnapshotStore sets the snapshot store.
func (app *BaseApp) SetSnapshotStore(snapshotStore *snapshots.Store) {
// SetSnapshot sets the snapshot store and options.
func (app *BaseApp) SetSnapshot(snapshotStore *snapshots.Store, opts snapshottypes.SnapshotOptions) {
if app.sealed {
panic("SetSnapshotStore() on sealed BaseApp")
panic("SetSnapshot() on sealed BaseApp")
}
if snapshotStore == nil {
if snapshotStore == nil || opts.Interval == snapshottypes.SnapshotIntervalOff {
app.snapshotManager = nil
return
}
app.snapshotManager = snapshots.NewManager(snapshotStore, app.cms, nil)
}
// SetSnapshotInterval sets the snapshot interval.
func (app *BaseApp) SetSnapshotInterval(snapshotInterval uint64) {
if app.sealed {
panic("SetSnapshotInterval() on sealed BaseApp")
}
app.snapshotInterval = snapshotInterval
}
// SetSnapshotKeepRecent sets the number of recent snapshots to keep.
func (app *BaseApp) SetSnapshotKeepRecent(snapshotKeepRecent uint32) {
if app.sealed {
panic("SetSnapshotKeepRecent() on sealed BaseApp")
}
app.snapshotKeepRecent = snapshotKeepRecent
app.cms.SetSnapshotInterval(opts.Interval)
app.snapshotManager = snapshots.NewManager(snapshotStore, opts, app.cms, nil, app.logger)
}
// SetInterfaceRegistry sets the InterfaceRegistry.
+12 -4
View File
@@ -1,8 +1,8 @@
package baseapp
import (
"github.com/cosmos/cosmos-sdk/snapshots"
"github.com/cosmos/cosmos-sdk/types"
sdk "github.com/cosmos/cosmos-sdk/types"
)
// TODO: Can be removed once we move all middleware tests into x/auth/middleware
@@ -31,10 +31,18 @@ func (app *BaseApp) CMS() types.CommitMultiStore {
return app.cms
}
// GetSnapshotManager() is an exported method to be able to access baseapp's snapshot
// manager in tests.
//
// This method is only accessible in baseapp tests.
func (app *BaseApp) GetSnapshotManager() *snapshots.Manager {
return app.snapshotManager
}
// GetMaximumBlockGas return maximum blocks gas.
//
// This method is only accessible in baseapp tests.
func (app *BaseApp) GetMaximumBlockGas(ctx sdk.Context) uint64 {
func (app *BaseApp) GetMaximumBlockGas(ctx types.Context) uint64 {
return app.getMaximumBlockGas(ctx)
}
@@ -48,13 +56,13 @@ func (app *BaseApp) GetName() string {
// CreateQueryContext calls app's createQueryContext.
//
// This method is only accessible in baseapp tests.
func (app *BaseApp) CreateQueryContext(height int64, prove bool) (sdk.Context, error) {
func (app *BaseApp) CreateQueryContext(height int64, prove bool) (types.Context, error) {
return app.createQueryContext(height, prove)
}
// MinGasPrices returns minGasPrices.
//
// This method is only accessible in baseapp tests.
func (app *BaseApp) MinGasPrices() sdk.DecCoins {
func (app *BaseApp) MinGasPrices() types.DecCoins {
return app.minGasPrices
}