github.com/Finschia/finschia-sdk@v0.48.1/baseapp/deliver_tx_test.go (about)

     1  package baseapp
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/binary"
     6  	"fmt"
     7  	"math/rand"
     8  	"os"
     9  	"strings"
    10  	"sync"
    11  	"testing"
    12  	"time"
    13  
    14  	"github.com/gogo/protobuf/jsonpb"
    15  	"github.com/stretchr/testify/assert"
    16  	"github.com/stretchr/testify/require"
    17  	abci "github.com/tendermint/tendermint/abci/types"
    18  	tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
    19  	dbm "github.com/tendermint/tm-db"
    20  
    21  	ocabci "github.com/Finschia/ostracon/abci/types"
    22  	"github.com/Finschia/ostracon/libs/log"
    23  
    24  	"github.com/Finschia/finschia-sdk/codec"
    25  	"github.com/Finschia/finschia-sdk/snapshots"
    26  	snapshottypes "github.com/Finschia/finschia-sdk/snapshots/types"
    27  	"github.com/Finschia/finschia-sdk/store/rootmulti"
    28  	store "github.com/Finschia/finschia-sdk/store/types"
    29  	"github.com/Finschia/finschia-sdk/testutil/testdata"
    30  	sdk "github.com/Finschia/finschia-sdk/types"
    31  	sdkerrors "github.com/Finschia/finschia-sdk/types/errors"
    32  )
    33  
    34  func TestLoadSnapshotChunk(t *testing.T) {
    35  	app, teardown := setupBaseAppWithSnapshots(t, 2, 5)
    36  	defer teardown()
    37  
    38  	testcases := map[string]struct {
    39  		height      uint64
    40  		format      uint32
    41  		chunk       uint32
    42  		expectEmpty bool
    43  	}{
    44  		"Existing snapshot": {2, 1, 1, false},
    45  		"Missing height":    {100, 1, 1, true},
    46  		"Missing format":    {2, 2, 1, true},
    47  		"Missing chunk":     {2, 1, 9, true},
    48  		"Zero height":       {0, 1, 1, true},
    49  		"Zero format":       {2, 0, 1, true},
    50  		"Zero chunk":        {2, 1, 0, false},
    51  	}
    52  	for name, tc := range testcases {
    53  		tc := tc
    54  		t.Run(name, func(t *testing.T) {
    55  			resp := app.LoadSnapshotChunk(abci.RequestLoadSnapshotChunk{
    56  				Height: tc.height,
    57  				Format: tc.format,
    58  				Chunk:  tc.chunk,
    59  			})
    60  			if tc.expectEmpty {
    61  				assert.Equal(t, abci.ResponseLoadSnapshotChunk{}, resp)
    62  				return
    63  			}
    64  			assert.NotEmpty(t, resp.Chunk)
    65  		})
    66  	}
    67  }
    68  
    69  func TestOfferSnapshot_Errors(t *testing.T) {
    70  	// Set up app before test cases, since it's fairly expensive.
    71  	app, teardown := setupBaseAppWithSnapshots(t, 0, 0)
    72  	defer teardown()
    73  
    74  	m := snapshottypes.Metadata{ChunkHashes: [][]byte{{1}, {2}, {3}}}
    75  	metadata, err := m.Marshal()
    76  	require.NoError(t, err)
    77  	hash := []byte{1, 2, 3}
    78  
    79  	testcases := map[string]struct {
    80  		snapshot *abci.Snapshot
    81  		result   abci.ResponseOfferSnapshot_Result
    82  	}{
    83  		"nil snapshot": {nil, abci.ResponseOfferSnapshot_REJECT},
    84  		"invalid format": {&abci.Snapshot{
    85  			Height: 1, Format: 9, Chunks: 3, Hash: hash, Metadata: metadata,
    86  		}, abci.ResponseOfferSnapshot_REJECT_FORMAT},
    87  		"incorrect chunk count": {&abci.Snapshot{
    88  			Height: 1, Format: 1, Chunks: 2, Hash: hash, Metadata: metadata,
    89  		}, abci.ResponseOfferSnapshot_REJECT},
    90  		"no chunks": {&abci.Snapshot{
    91  			Height: 1, Format: 1, Chunks: 0, Hash: hash, Metadata: metadata,
    92  		}, abci.ResponseOfferSnapshot_REJECT},
    93  		"invalid metadata serialization": {&abci.Snapshot{
    94  			Height: 1, Format: 1, Chunks: 0, Hash: hash, Metadata: []byte{3, 1, 4},
    95  		}, abci.ResponseOfferSnapshot_REJECT},
    96  	}
    97  	for name, tc := range testcases {
    98  		tc := tc
    99  		t.Run(name, func(t *testing.T) {
   100  			resp := app.OfferSnapshot(abci.RequestOfferSnapshot{Snapshot: tc.snapshot})
   101  			assert.Equal(t, tc.result, resp.Result)
   102  		})
   103  	}
   104  
   105  	// Offering a snapshot after one has been accepted should error
   106  	resp := app.OfferSnapshot(abci.RequestOfferSnapshot{Snapshot: &abci.Snapshot{
   107  		Height:   1,
   108  		Format:   snapshottypes.CurrentFormat,
   109  		Chunks:   3,
   110  		Hash:     []byte{1, 2, 3},
   111  		Metadata: metadata,
   112  	}})
   113  	require.Equal(t, abci.ResponseOfferSnapshot{Result: abci.ResponseOfferSnapshot_ACCEPT}, resp)
   114  
   115  	resp = app.OfferSnapshot(abci.RequestOfferSnapshot{Snapshot: &abci.Snapshot{
   116  		Height:   2,
   117  		Format:   snapshottypes.CurrentFormat,
   118  		Chunks:   3,
   119  		Hash:     []byte{1, 2, 3},
   120  		Metadata: metadata,
   121  	}})
   122  	require.Equal(t, abci.ResponseOfferSnapshot{Result: abci.ResponseOfferSnapshot_ABORT}, resp)
   123  }
   124  
   125  func TestApplySnapshotChunk(t *testing.T) {
   126  	source, teardown := setupBaseAppWithSnapshots(t, 4, 10)
   127  	defer teardown()
   128  
   129  	target, teardown := setupBaseAppWithSnapshots(t, 0, 0)
   130  	defer teardown()
   131  
   132  	// Fetch latest snapshot to restore
   133  	respList := source.ListSnapshots(abci.RequestListSnapshots{})
   134  	require.NotEmpty(t, respList.Snapshots)
   135  	snapshot := respList.Snapshots[0]
   136  
   137  	// Make sure the snapshot has at least 3 chunks
   138  	require.GreaterOrEqual(t, snapshot.Chunks, uint32(3), "Not enough snapshot chunks")
   139  
   140  	// Begin a snapshot restoration in the target
   141  	respOffer := target.OfferSnapshot(abci.RequestOfferSnapshot{Snapshot: snapshot})
   142  	require.Equal(t, abci.ResponseOfferSnapshot{Result: abci.ResponseOfferSnapshot_ACCEPT}, respOffer)
   143  
   144  	// We should be able to pass an invalid chunk and get a verify failure, before reapplying it.
   145  	respApply := target.ApplySnapshotChunk(abci.RequestApplySnapshotChunk{
   146  		Index:  0,
   147  		Chunk:  []byte{9},
   148  		Sender: "sender",
   149  	})
   150  	require.Equal(t, abci.ResponseApplySnapshotChunk{
   151  		Result:        abci.ResponseApplySnapshotChunk_RETRY,
   152  		RefetchChunks: []uint32{0},
   153  		RejectSenders: []string{"sender"},
   154  	}, respApply)
   155  
   156  	// Fetch each chunk from the source and apply it to the target
   157  	for index := uint32(0); index < snapshot.Chunks; index++ {
   158  		respChunk := source.LoadSnapshotChunk(abci.RequestLoadSnapshotChunk{
   159  			Height: snapshot.Height,
   160  			Format: snapshot.Format,
   161  			Chunk:  index,
   162  		})
   163  		require.NotNil(t, respChunk.Chunk)
   164  		respApply := target.ApplySnapshotChunk(abci.RequestApplySnapshotChunk{
   165  			Index: index,
   166  			Chunk: respChunk.Chunk,
   167  		})
   168  		require.Equal(t, abci.ResponseApplySnapshotChunk{
   169  			Result: abci.ResponseApplySnapshotChunk_ACCEPT,
   170  		}, respApply)
   171  	}
   172  
   173  	// The target should now have the same hash as the source
   174  	assert.Equal(t, source.LastCommitID(), target.LastCommitID())
   175  }
   176  
   177  // NOTE: represents a new custom router for testing purposes of WithRouter()
   178  type testCustomRouter struct {
   179  	routes sync.Map
   180  }
   181  
   182  func (rtr *testCustomRouter) AddRoute(route sdk.Route) sdk.Router {
   183  	rtr.routes.Store(route.Path(), route.Handler())
   184  	return rtr
   185  }
   186  
   187  func (rtr *testCustomRouter) Route(ctx sdk.Context, path string) sdk.Handler {
   188  	if v, ok := rtr.routes.Load(path); ok {
   189  		if h, ok := v.(sdk.Handler); ok {
   190  			return h
   191  		}
   192  	}
   193  	return nil
   194  }
   195  
   196  func TestWithRouter(t *testing.T) {
   197  	// test increments in the ante
   198  	anteKey := []byte("ante-key")
   199  	anteOpt := func(bapp *BaseApp) { bapp.SetAnteHandler(anteHandlerTxTest(t, capKey1, anteKey)) }
   200  
   201  	// test increments in the handler
   202  	deliverKey := []byte("deliver-key")
   203  	routerOpt := func(bapp *BaseApp) {
   204  		bapp.SetRouter(&testCustomRouter{routes: sync.Map{}})
   205  		r := sdk.NewRoute(routeMsgCounter, handlerMsgCounter(t, capKey1, deliverKey))
   206  		bapp.Router().AddRoute(r)
   207  	}
   208  
   209  	app := setupBaseApp(t, anteOpt, routerOpt)
   210  	app.InitChain(abci.RequestInitChain{})
   211  
   212  	// Create same codec used in txDecoder
   213  	codec := codec.NewLegacyAmino()
   214  	registerTestCodec(codec)
   215  
   216  	nBlocks := 3
   217  	txPerHeight := 5
   218  
   219  	for blockN := 0; blockN < nBlocks; blockN++ {
   220  		header := tmproto.Header{Height: int64(blockN) + 1}
   221  		app.BeginBlock(ocabci.RequestBeginBlock{Header: header})
   222  
   223  		for i := 0; i < txPerHeight; i++ {
   224  			counter := int64(blockN*txPerHeight + i)
   225  			tx := newTxCounter(counter, counter)
   226  
   227  			txBytes, err := codec.Marshal(tx)
   228  			require.NoError(t, err)
   229  
   230  			res := app.DeliverTx(abci.RequestDeliverTx{Tx: txBytes})
   231  			require.True(t, res.IsOK(), fmt.Sprintf("%v", res))
   232  		}
   233  
   234  		app.EndBlock(abci.RequestEndBlock{})
   235  		app.Commit()
   236  	}
   237  }
   238  
   239  func TestBaseApp_EndBlock(t *testing.T) {
   240  	db := dbm.NewMemDB()
   241  	name := t.Name()
   242  	logger := defaultLogger()
   243  
   244  	cp := &abci.ConsensusParams{
   245  		Block: &abci.BlockParams{
   246  			MaxGas: 5000000,
   247  		},
   248  	}
   249  
   250  	app := NewBaseApp(name, logger, db, nil)
   251  	app.SetParamStore(&paramStore{db: dbm.NewMemDB()})
   252  	app.InitChain(abci.RequestInitChain{
   253  		ConsensusParams: cp,
   254  	})
   255  
   256  	app.SetEndBlocker(func(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock {
   257  		return abci.ResponseEndBlock{
   258  			ValidatorUpdates: []abci.ValidatorUpdate{
   259  				{Power: 100},
   260  			},
   261  		}
   262  	})
   263  	app.Seal()
   264  
   265  	res := app.EndBlock(abci.RequestEndBlock{})
   266  	require.Len(t, res.GetValidatorUpdates(), 1)
   267  	require.Equal(t, int64(100), res.GetValidatorUpdates()[0].Power)
   268  	require.Equal(t, cp.Block.MaxGas, res.ConsensusParamUpdates.Block.MaxGas)
   269  }
   270  
   271  // Test that we can only query from the latest committed state.
   272  func TestQuery(t *testing.T) {
   273  	key, value := []byte("hello"), []byte("goodbye")
   274  	anteOpt := func(bapp *BaseApp) {
   275  		bapp.SetAnteHandler(func(ctx sdk.Context, tx sdk.Tx, simulate bool) (newCtx sdk.Context, err error) {
   276  			store := ctx.KVStore(capKey1)
   277  			store.Set(key, value)
   278  			return
   279  		})
   280  	}
   281  
   282  	routerOpt := func(bapp *BaseApp) {
   283  		r := sdk.NewRoute(routeMsgCounter, func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) {
   284  			store := ctx.KVStore(capKey1)
   285  			store.Set(key, value)
   286  			return &sdk.Result{}, nil
   287  		})
   288  		bapp.Router().AddRoute(r)
   289  	}
   290  
   291  	app := setupBaseApp(t, anteOpt, routerOpt)
   292  
   293  	app.InitChain(abci.RequestInitChain{})
   294  
   295  	// NOTE: "/store/key1" tells us KVStore
   296  	// and the final "/key" says to use the data as the
   297  	// key in the given KVStore ...
   298  	query := abci.RequestQuery{
   299  		Path: "/store/key1/key",
   300  		Data: key,
   301  	}
   302  	tx := newTxCounter(0, 0)
   303  
   304  	// query is empty before we do anything
   305  	res := app.Query(query)
   306  	require.Equal(t, 0, len(res.Value))
   307  
   308  	// query is still empty after a CheckTx
   309  	_, err := app.Check(aminoTxEncoder(), tx)
   310  	require.NoError(t, err)
   311  	res = app.Query(query)
   312  	require.Equal(t, 0, len(res.Value))
   313  
   314  	// query is still empty after a DeliverTx before we commit
   315  	header := tmproto.Header{Height: app.LastBlockHeight() + 1}
   316  	app.BeginBlock(ocabci.RequestBeginBlock{Header: header})
   317  
   318  	_, resTx, err := app.Deliver(aminoTxEncoder(), tx)
   319  	require.NoError(t, err)
   320  	require.NotNil(t, resTx)
   321  	res = app.Query(query)
   322  	require.Equal(t, 0, len(res.Value))
   323  
   324  	// query returns correct value after Commit
   325  	app.Commit()
   326  	res = app.Query(query)
   327  	require.Equal(t, value, res.Value)
   328  }
   329  
   330  func TestGRPCQuery(t *testing.T) {
   331  	grpcQueryOpt := func(bapp *BaseApp) {
   332  		testdata.RegisterQueryServer(
   333  			bapp.GRPCQueryRouter(),
   334  			testdata.QueryImpl{},
   335  		)
   336  	}
   337  
   338  	app := setupBaseApp(t, grpcQueryOpt)
   339  
   340  	app.InitChain(abci.RequestInitChain{})
   341  	header := tmproto.Header{Height: app.LastBlockHeight() + 1}
   342  	app.BeginBlock(ocabci.RequestBeginBlock{Header: header})
   343  	app.Commit()
   344  
   345  	req := testdata.SayHelloRequest{Name: "foo"}
   346  	reqBz, err := req.Marshal()
   347  	require.NoError(t, err)
   348  
   349  	reqQuery := abci.RequestQuery{
   350  		Data: reqBz,
   351  		Path: "/testdata.Query/SayHello",
   352  	}
   353  
   354  	resQuery := app.Query(reqQuery)
   355  
   356  	require.Equal(t, abci.CodeTypeOK, resQuery.Code, resQuery)
   357  
   358  	var res testdata.SayHelloResponse
   359  	err = res.Unmarshal(resQuery.Value)
   360  	require.NoError(t, err)
   361  	require.Equal(t, "Hello foo!", res.Greeting)
   362  }
   363  
   364  // Test p2p filter queries
   365  func TestP2PQuery(t *testing.T) {
   366  	addrPeerFilterOpt := func(bapp *BaseApp) {
   367  		bapp.SetAddrPeerFilter(func(addrport string) abci.ResponseQuery {
   368  			require.Equal(t, "1.1.1.1:8000", addrport)
   369  			return abci.ResponseQuery{Code: uint32(3)}
   370  		})
   371  	}
   372  
   373  	idPeerFilterOpt := func(bapp *BaseApp) {
   374  		bapp.SetIDPeerFilter(func(id string) abci.ResponseQuery {
   375  			require.Equal(t, "testid", id)
   376  			return abci.ResponseQuery{Code: uint32(4)}
   377  		})
   378  	}
   379  
   380  	app := setupBaseApp(t, addrPeerFilterOpt, idPeerFilterOpt)
   381  
   382  	addrQuery := abci.RequestQuery{
   383  		Path: "/p2p/filter/addr/1.1.1.1:8000",
   384  	}
   385  	res := app.Query(addrQuery)
   386  	require.Equal(t, uint32(3), res.Code)
   387  
   388  	idQuery := abci.RequestQuery{
   389  		Path: "/p2p/filter/id/testid",
   390  	}
   391  	res = app.Query(idQuery)
   392  	require.Equal(t, uint32(4), res.Code)
   393  }
   394  
   395  // One call to DeliverTx should process all the messages, in order.
   396  func TestMultiMsgDeliverTx(t *testing.T) {
   397  	// increment the tx counter
   398  	anteKey := []byte("ante-key")
   399  	anteOpt := func(bapp *BaseApp) { bapp.SetAnteHandler(anteHandlerTxTest(t, capKey1, anteKey)) }
   400  
   401  	// increment the msg counter
   402  	deliverKey := []byte("deliver-key")
   403  	deliverKey2 := []byte("deliver-key2")
   404  	routerOpt := func(bapp *BaseApp) {
   405  		r1 := sdk.NewRoute(routeMsgCounter, handlerMsgCounter(t, capKey1, deliverKey))
   406  		r2 := sdk.NewRoute(routeMsgCounter2, handlerMsgCounter(t, capKey1, deliverKey2))
   407  		bapp.Router().AddRoute(r1)
   408  		bapp.Router().AddRoute(r2)
   409  	}
   410  
   411  	app := setupBaseApp(t, anteOpt, routerOpt)
   412  
   413  	// Create same codec used in txDecoder
   414  	codec := codec.NewLegacyAmino()
   415  	registerTestCodec(codec)
   416  
   417  	// run a multi-msg tx
   418  	// with all msgs the same route
   419  
   420  	header := tmproto.Header{Height: 1}
   421  	app.BeginBlock(ocabci.RequestBeginBlock{Header: header})
   422  	tx := newTxCounter(0, 0, 1, 2)
   423  	txBytes, err := codec.Marshal(tx)
   424  	require.NoError(t, err)
   425  	res := app.DeliverTx(abci.RequestDeliverTx{Tx: txBytes})
   426  	require.True(t, res.IsOK(), fmt.Sprintf("%v", res))
   427  
   428  	store := app.deliverState.ctx.KVStore(capKey1)
   429  
   430  	// tx counter only incremented once
   431  	txCounter := getIntFromStore(store, anteKey)
   432  	require.Equal(t, int64(1), txCounter)
   433  
   434  	// msg counter incremented three times
   435  	msgCounter := getIntFromStore(store, deliverKey)
   436  	require.Equal(t, int64(3), msgCounter)
   437  
   438  	// replace the second message with a msgCounter2
   439  
   440  	tx = newTxCounter(1, 3)
   441  	tx.Msgs = append(tx.Msgs, msgCounter2{0})
   442  	tx.Msgs = append(tx.Msgs, msgCounter2{1})
   443  	txBytes, err = codec.Marshal(tx)
   444  	require.NoError(t, err)
   445  	res = app.DeliverTx(abci.RequestDeliverTx{Tx: txBytes})
   446  	require.True(t, res.IsOK(), fmt.Sprintf("%v", res))
   447  
   448  	store = app.deliverState.ctx.KVStore(capKey1)
   449  
   450  	// tx counter only incremented once
   451  	txCounter = getIntFromStore(store, anteKey)
   452  	require.Equal(t, int64(2), txCounter)
   453  
   454  	// original counter increments by one
   455  	// new counter increments by two
   456  	msgCounter = getIntFromStore(store, deliverKey)
   457  	require.Equal(t, int64(4), msgCounter)
   458  	msgCounter2 := getIntFromStore(store, deliverKey2)
   459  	require.Equal(t, int64(2), msgCounter2)
   460  }
   461  
   462  // Interleave calls to Check and Deliver and ensure
   463  // that there is no cross-talk. Check sees results of the previous Check calls
   464  // and Deliver sees that of the previous Deliver calls, but they don't see eachother.
   465  func TestConcurrentCheckDeliver(t *testing.T) {
   466  	// TODO
   467  }
   468  
   469  // Simulate a transaction that uses gas to compute the gas.
   470  // Simulate() and Query("/app/simulate", txBytes) should give
   471  // the same results.
   472  func TestSimulateTx(t *testing.T) {
   473  	gasConsumed := uint64(5)
   474  
   475  	anteOpt := func(bapp *BaseApp) {
   476  		bapp.SetAnteHandler(func(ctx sdk.Context, tx sdk.Tx, simulate bool) (newCtx sdk.Context, err error) {
   477  			newCtx = ctx.WithGasMeter(sdk.NewGasMeter(gasConsumed))
   478  			return
   479  		})
   480  	}
   481  
   482  	routerOpt := func(bapp *BaseApp) {
   483  		r := sdk.NewRoute(routeMsgCounter, func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) {
   484  			ctx.GasMeter().ConsumeGas(gasConsumed, "test")
   485  			return &sdk.Result{}, nil
   486  		})
   487  		bapp.Router().AddRoute(r)
   488  	}
   489  
   490  	app := setupBaseApp(t, anteOpt, routerOpt)
   491  
   492  	app.InitChain(abci.RequestInitChain{})
   493  
   494  	// Create same codec used in txDecoder
   495  	cdc := codec.NewLegacyAmino()
   496  	registerTestCodec(cdc)
   497  
   498  	nBlocks := 3
   499  	for blockN := 0; blockN < nBlocks; blockN++ {
   500  		count := int64(blockN + 1)
   501  		header := tmproto.Header{Height: count}
   502  		app.BeginBlock(ocabci.RequestBeginBlock{Header: header})
   503  
   504  		tx := newTxCounter(count, count)
   505  		txBytes, err := cdc.Marshal(tx)
   506  		require.Nil(t, err)
   507  
   508  		// simulate a message, check gas reported
   509  		gInfo, result, err := app.Simulate(txBytes)
   510  		require.NoError(t, err)
   511  		require.NotNil(t, result)
   512  		require.Equal(t, gasConsumed, gInfo.GasUsed)
   513  
   514  		// simulate again, same result
   515  		gInfo, result, err = app.Simulate(txBytes)
   516  		require.NoError(t, err)
   517  		require.NotNil(t, result)
   518  		require.Equal(t, gasConsumed, gInfo.GasUsed)
   519  
   520  		// simulate by calling Query with encoded tx
   521  		query := abci.RequestQuery{
   522  			Path: "/app/simulate",
   523  			Data: txBytes,
   524  		}
   525  		queryResult := app.Query(query)
   526  		require.True(t, queryResult.IsOK(), queryResult.Log)
   527  
   528  		var simRes sdk.SimulationResponse
   529  		require.NoError(t, jsonpb.Unmarshal(strings.NewReader(string(queryResult.Value)), &simRes))
   530  
   531  		require.Equal(t, gInfo, simRes.GasInfo)
   532  		require.Equal(t, result.Log, simRes.Result.Log)
   533  		require.Equal(t, result.Events, simRes.Result.Events)
   534  		require.True(t, bytes.Equal(result.Data, simRes.Result.Data))
   535  
   536  		app.EndBlock(abci.RequestEndBlock{})
   537  		app.Commit()
   538  	}
   539  }
   540  
   541  func TestRunInvalidTransaction(t *testing.T) {
   542  	anteOpt := func(bapp *BaseApp) {
   543  		bapp.SetAnteHandler(func(ctx sdk.Context, tx sdk.Tx, simulate bool) (newCtx sdk.Context, err error) {
   544  			return
   545  		})
   546  	}
   547  	routerOpt := func(bapp *BaseApp) {
   548  		r := sdk.NewRoute(routeMsgCounter, func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) {
   549  			return &sdk.Result{}, nil
   550  		})
   551  		bapp.Router().AddRoute(r)
   552  	}
   553  
   554  	app := setupBaseApp(t, anteOpt, routerOpt)
   555  
   556  	header := tmproto.Header{Height: 1}
   557  	app.BeginBlock(ocabci.RequestBeginBlock{Header: header})
   558  
   559  	// transaction with no messages
   560  	{
   561  		emptyTx := &txTest{}
   562  		_, result, err := app.Deliver(aminoTxEncoder(), emptyTx)
   563  		require.Error(t, err)
   564  		require.Nil(t, result)
   565  
   566  		space, code, _ := sdkerrors.ABCIInfo(err, false)
   567  		require.EqualValues(t, sdkerrors.ErrInvalidRequest.Codespace(), space, err)
   568  		require.EqualValues(t, sdkerrors.ErrInvalidRequest.ABCICode(), code, err)
   569  	}
   570  
   571  	// transaction where ValidateBasic fails
   572  	{
   573  		testCases := []struct {
   574  			tx   *txTest
   575  			fail bool
   576  		}{
   577  			{newTxCounter(0, 0), false},
   578  			{newTxCounter(-1, 0), false},
   579  			{newTxCounter(100, 100), false},
   580  			{newTxCounter(100, 5, 4, 3, 2, 1), false},
   581  
   582  			{newTxCounter(0, -1), true},
   583  			{newTxCounter(0, 1, -2), true},
   584  			{newTxCounter(0, 1, 2, -10, 5), true},
   585  		}
   586  
   587  		for _, testCase := range testCases {
   588  			tx := testCase.tx
   589  			_, result, err := app.Deliver(aminoTxEncoder(), tx)
   590  
   591  			if testCase.fail {
   592  				require.Error(t, err)
   593  
   594  				space, code, _ := sdkerrors.ABCIInfo(err, false)
   595  				require.EqualValues(t, sdkerrors.ErrInvalidSequence.Codespace(), space, err)
   596  				require.EqualValues(t, sdkerrors.ErrInvalidSequence.ABCICode(), code, err)
   597  			} else {
   598  				require.NotNil(t, result)
   599  			}
   600  		}
   601  	}
   602  
   603  	// transaction with no known route
   604  	{
   605  		unknownRouteTx := txTest{[]sdk.Msg{msgNoRoute{}}, 0, false}
   606  		_, result, err := app.Deliver(aminoTxEncoder(), unknownRouteTx)
   607  		require.Error(t, err)
   608  		require.Nil(t, result)
   609  
   610  		space, code, _ := sdkerrors.ABCIInfo(err, false)
   611  		require.EqualValues(t, sdkerrors.ErrUnknownRequest.Codespace(), space, err)
   612  		require.EqualValues(t, sdkerrors.ErrUnknownRequest.ABCICode(), code, err)
   613  
   614  		unknownRouteTx = txTest{[]sdk.Msg{msgCounter{}, msgNoRoute{}}, 0, false}
   615  		_, result, err = app.Deliver(aminoTxEncoder(), unknownRouteTx)
   616  		require.Error(t, err)
   617  		require.Nil(t, result)
   618  
   619  		space, code, _ = sdkerrors.ABCIInfo(err, false)
   620  		require.EqualValues(t, sdkerrors.ErrUnknownRequest.Codespace(), space, err)
   621  		require.EqualValues(t, sdkerrors.ErrUnknownRequest.ABCICode(), code, err)
   622  	}
   623  
   624  	// Transaction with an unregistered message
   625  	{
   626  		tx := newTxCounter(0, 0)
   627  		tx.Msgs = append(tx.Msgs, msgNoDecode{})
   628  
   629  		// new codec so we can encode the tx, but we shouldn't be able to decode
   630  		newCdc := codec.NewLegacyAmino()
   631  		registerTestCodec(newCdc)
   632  		newCdc.RegisterConcrete(&msgNoDecode{}, "cosmos-sdk/baseapp/msgNoDecode", nil)
   633  
   634  		txBytes, err := newCdc.Marshal(tx)
   635  		require.NoError(t, err)
   636  
   637  		res := app.DeliverTx(abci.RequestDeliverTx{Tx: txBytes})
   638  		require.EqualValues(t, sdkerrors.ErrTxDecode.ABCICode(), res.Code)
   639  		require.EqualValues(t, sdkerrors.ErrTxDecode.Codespace(), res.Codespace)
   640  	}
   641  }
   642  
   643  // Test that transactions exceeding gas limits fail
   644  func TestTxGasLimits(t *testing.T) {
   645  	gasGranted := uint64(10)
   646  	anteOpt := func(bapp *BaseApp) {
   647  		bapp.SetAnteHandler(func(ctx sdk.Context, tx sdk.Tx, simulate bool) (newCtx sdk.Context, err error) {
   648  			newCtx = ctx.WithGasMeter(sdk.NewGasMeter(gasGranted))
   649  
   650  			// AnteHandlers must have their own defer/recover in order for the BaseApp
   651  			// to know how much gas was used! This is because the GasMeter is created in
   652  			// the AnteHandler, but if it panics the context won't be set properly in
   653  			// runTx's recover call.
   654  			defer func() {
   655  				if r := recover(); r != nil {
   656  					switch rType := r.(type) {
   657  					case sdk.ErrorOutOfGas:
   658  						err = sdkerrors.Wrapf(sdkerrors.ErrOutOfGas, "out of gas in location: %v", rType.Descriptor)
   659  					default:
   660  						panic(r)
   661  					}
   662  				}
   663  			}()
   664  
   665  			count := tx.(*txTest).Counter
   666  			newCtx.GasMeter().ConsumeGas(uint64(count), "counter-ante")
   667  
   668  			return newCtx, nil
   669  		})
   670  	}
   671  
   672  	routerOpt := func(bapp *BaseApp) {
   673  		r := sdk.NewRoute(routeMsgCounter, func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) {
   674  			count := msg.(msgCounter).Counter
   675  			ctx.GasMeter().ConsumeGas(uint64(count), "counter-handler")
   676  			return &sdk.Result{}, nil
   677  		})
   678  		bapp.Router().AddRoute(r)
   679  	}
   680  
   681  	app := setupBaseApp(t, anteOpt, routerOpt)
   682  
   683  	header := tmproto.Header{Height: 1}
   684  	app.BeginBlock(ocabci.RequestBeginBlock{Header: header})
   685  
   686  	testCases := []struct {
   687  		tx      *txTest
   688  		gasUsed uint64
   689  		fail    bool
   690  	}{
   691  		{newTxCounter(0, 0), 0, false},
   692  		{newTxCounter(1, 1), 2, false},
   693  		{newTxCounter(9, 1), 10, false},
   694  		{newTxCounter(1, 9), 10, false},
   695  		{newTxCounter(10, 0), 10, false},
   696  		{newTxCounter(0, 10), 10, false},
   697  		{newTxCounter(0, 8, 2), 10, false},
   698  		{newTxCounter(0, 5, 1, 1, 1, 1, 1), 10, false},
   699  		{newTxCounter(0, 5, 1, 1, 1, 1), 9, false},
   700  
   701  		{newTxCounter(9, 2), 11, true},
   702  		{newTxCounter(2, 9), 11, true},
   703  		{newTxCounter(9, 1, 1), 11, true},
   704  		{newTxCounter(1, 8, 1, 1), 11, true},
   705  		{newTxCounter(11, 0), 11, true},
   706  		{newTxCounter(0, 11), 11, true},
   707  		{newTxCounter(0, 5, 11), 16, true},
   708  	}
   709  
   710  	for i, tc := range testCases {
   711  		tx := tc.tx
   712  		gInfo, result, err := app.Deliver(aminoTxEncoder(), tx)
   713  
   714  		// check gas used and wanted
   715  		require.Equal(t, tc.gasUsed, gInfo.GasUsed, fmt.Sprintf("tc #%d; gas: %v, result: %v, err: %s", i, gInfo, result, err))
   716  
   717  		// check for out of gas
   718  		if !tc.fail {
   719  			require.NotNil(t, result, fmt.Sprintf("%d: %v, %v", i, tc, err))
   720  		} else {
   721  			require.Error(t, err)
   722  			require.Nil(t, result)
   723  
   724  			space, code, _ := sdkerrors.ABCIInfo(err, false)
   725  			require.EqualValues(t, sdkerrors.ErrOutOfGas.Codespace(), space, err)
   726  			require.EqualValues(t, sdkerrors.ErrOutOfGas.ABCICode(), code, err)
   727  		}
   728  	}
   729  }
   730  
   731  // Test that transactions exceeding gas limits fail
   732  func TestMaxBlockGasLimits(t *testing.T) {
   733  	gasGranted := uint64(10)
   734  	anteOpt := func(bapp *BaseApp) {
   735  		bapp.SetAnteHandler(func(ctx sdk.Context, tx sdk.Tx, simulate bool) (newCtx sdk.Context, err error) {
   736  			newCtx = ctx.WithGasMeter(sdk.NewGasMeter(gasGranted))
   737  
   738  			defer func() {
   739  				if r := recover(); r != nil {
   740  					switch rType := r.(type) {
   741  					case sdk.ErrorOutOfGas:
   742  						err = sdkerrors.Wrapf(sdkerrors.ErrOutOfGas, "out of gas in location: %v", rType.Descriptor)
   743  					default:
   744  						panic(r)
   745  					}
   746  				}
   747  			}()
   748  
   749  			count := tx.(*txTest).Counter
   750  			newCtx.GasMeter().ConsumeGas(uint64(count), "counter-ante")
   751  
   752  			return
   753  		})
   754  	}
   755  
   756  	routerOpt := func(bapp *BaseApp) {
   757  		r := sdk.NewRoute(routeMsgCounter, func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) {
   758  			count := msg.(msgCounter).Counter
   759  			ctx.GasMeter().ConsumeGas(uint64(count), "counter-handler")
   760  			return &sdk.Result{}, nil
   761  		})
   762  		bapp.Router().AddRoute(r)
   763  	}
   764  
   765  	app := setupBaseApp(t, anteOpt, routerOpt)
   766  	app.InitChain(abci.RequestInitChain{
   767  		ConsensusParams: &abci.ConsensusParams{
   768  			Block: &abci.BlockParams{
   769  				MaxGas: 100,
   770  			},
   771  		},
   772  	})
   773  
   774  	testCases := []struct {
   775  		tx                *txTest
   776  		numDelivers       int
   777  		gasUsedPerDeliver uint64
   778  		fail              bool
   779  		failAfterDeliver  int
   780  	}{
   781  		{newTxCounter(0, 0), 0, 0, false, 0},
   782  		{newTxCounter(9, 1), 2, 10, false, 0},
   783  		{newTxCounter(10, 0), 3, 10, false, 0},
   784  		{newTxCounter(10, 0), 10, 10, false, 0},
   785  		{newTxCounter(2, 7), 11, 9, false, 0},
   786  		{newTxCounter(10, 0), 10, 10, false, 0}, // hit the limit but pass
   787  
   788  		{newTxCounter(10, 0), 11, 10, true, 10},
   789  		{newTxCounter(10, 0), 15, 10, true, 10},
   790  		{newTxCounter(9, 0), 12, 9, true, 11}, // fly past the limit
   791  	}
   792  
   793  	for i, tc := range testCases {
   794  		tx := tc.tx
   795  
   796  		// reset the block gas
   797  		header := tmproto.Header{Height: app.LastBlockHeight() + 1}
   798  		app.BeginBlock(ocabci.RequestBeginBlock{Header: header})
   799  
   800  		// execute the transaction multiple times
   801  		for j := 0; j < tc.numDelivers; j++ {
   802  			_, result, err := app.Deliver(aminoTxEncoder(), tx)
   803  
   804  			ctx := app.deliverState.ctx
   805  
   806  			// check for failed transactions
   807  			if tc.fail && (j+1) > tc.failAfterDeliver {
   808  				require.Error(t, err, fmt.Sprintf("tc #%d; result: %v, err: %s", i, result, err))
   809  				require.Nil(t, result, fmt.Sprintf("tc #%d; result: %v, err: %s", i, result, err))
   810  
   811  				space, code, _ := sdkerrors.ABCIInfo(err, false)
   812  				require.EqualValues(t, sdkerrors.ErrOutOfGas.Codespace(), space, err)
   813  				require.EqualValues(t, sdkerrors.ErrOutOfGas.ABCICode(), code, err)
   814  				require.True(t, ctx.BlockGasMeter().IsOutOfGas())
   815  			} else {
   816  				// check gas used and wanted
   817  				blockGasUsed := ctx.BlockGasMeter().GasConsumed()
   818  				expBlockGasUsed := tc.gasUsedPerDeliver * uint64(j+1)
   819  				require.Equal(
   820  					t, expBlockGasUsed, blockGasUsed,
   821  					fmt.Sprintf("%d,%d: %v, %v, %v, %v", i, j, tc, expBlockGasUsed, blockGasUsed, result),
   822  				)
   823  
   824  				require.NotNil(t, result, fmt.Sprintf("tc #%d; currDeliver: %d, result: %v, err: %s", i, j, result, err))
   825  				require.False(t, ctx.BlockGasMeter().IsPastLimit())
   826  			}
   827  		}
   828  	}
   829  }
   830  
   831  // Test custom panic handling within app.DeliverTx method
   832  func TestCustomRunTxPanicHandler(t *testing.T) {
   833  	const customPanicMsg = "test panic"
   834  	anteErr := sdkerrors.Register("fakeModule", 100500, "fakeError")
   835  
   836  	anteOpt := func(bapp *BaseApp) {
   837  		bapp.SetAnteHandler(func(ctx sdk.Context, tx sdk.Tx, simulate bool) (newCtx sdk.Context, err error) {
   838  			panic(sdkerrors.Wrap(anteErr, "anteHandler"))
   839  		})
   840  	}
   841  	routerOpt := func(bapp *BaseApp) {
   842  		r := sdk.NewRoute(routeMsgCounter, func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) {
   843  			return &sdk.Result{}, nil
   844  		})
   845  		bapp.Router().AddRoute(r)
   846  	}
   847  
   848  	app := setupBaseApp(t, anteOpt, routerOpt)
   849  
   850  	header := tmproto.Header{Height: 1}
   851  	app.BeginBlock(ocabci.RequestBeginBlock{Header: header})
   852  
   853  	app.AddRunTxRecoveryHandler(func(recoveryObj interface{}) error {
   854  		err, ok := recoveryObj.(error)
   855  		if !ok {
   856  			return nil
   857  		}
   858  
   859  		if anteErr.Is(err) {
   860  			panic(customPanicMsg)
   861  		} else {
   862  			return nil
   863  		}
   864  	})
   865  
   866  	// Transaction should panic with custom handler above
   867  	{
   868  		tx := newTxCounter(0, 0)
   869  
   870  		require.PanicsWithValue(t, customPanicMsg, func() { app.Deliver(aminoTxEncoder(), tx) })
   871  	}
   872  }
   873  
   874  func TestBaseAppAnteHandler(t *testing.T) {
   875  	anteKey := []byte("ante-key")
   876  	anteOpt := func(bapp *BaseApp) {
   877  		bapp.SetAnteHandler(anteHandlerTxTest(t, capKey1, anteKey))
   878  	}
   879  
   880  	deliverKey := []byte("deliver-key")
   881  	routerOpt := func(bapp *BaseApp) {
   882  		r := sdk.NewRoute(routeMsgCounter, handlerMsgCounter(t, capKey1, deliverKey))
   883  		bapp.Router().AddRoute(r)
   884  	}
   885  
   886  	cdc := codec.NewLegacyAmino()
   887  	app := setupBaseApp(t, anteOpt, routerOpt)
   888  
   889  	app.InitChain(abci.RequestInitChain{})
   890  	registerTestCodec(cdc)
   891  
   892  	header := tmproto.Header{Height: app.LastBlockHeight() + 1}
   893  	app.BeginBlock(ocabci.RequestBeginBlock{Header: header})
   894  
   895  	// execute a tx that will fail ante handler execution
   896  	//
   897  	// NOTE: State should not be mutated here. This will be implicitly checked by
   898  	// the next txs ante handler execution (anteHandlerTxTest).
   899  	tx := newTxCounter(0, 0)
   900  	tx.setFailOnAnte(true)
   901  	txBytes, err := cdc.Marshal(tx)
   902  	require.NoError(t, err)
   903  	res := app.DeliverTx(abci.RequestDeliverTx{Tx: txBytes})
   904  	require.Empty(t, res.Events)
   905  	require.False(t, res.IsOK(), fmt.Sprintf("%v", res))
   906  
   907  	ctx := app.deliverState.ctx
   908  	store := ctx.KVStore(capKey1)
   909  	require.Equal(t, int64(0), getIntFromStore(store, anteKey))
   910  
   911  	// execute at tx that will pass the ante handler (the checkTx state should
   912  	// mutate) but will fail the message handler
   913  	tx = newTxCounter(0, 0)
   914  	tx.setFailOnHandler(true)
   915  
   916  	txBytes, err = cdc.Marshal(tx)
   917  	require.NoError(t, err)
   918  
   919  	res = app.DeliverTx(abci.RequestDeliverTx{Tx: txBytes})
   920  	// should emit ante event
   921  	require.NotEmpty(t, res.Events)
   922  	require.False(t, res.IsOK(), fmt.Sprintf("%v", res))
   923  
   924  	ctx = app.deliverState.ctx
   925  	store = ctx.KVStore(capKey1)
   926  	require.Equal(t, int64(1), getIntFromStore(store, anteKey))
   927  	require.Equal(t, int64(0), getIntFromStore(store, deliverKey))
   928  
   929  	// execute a successful ante handler and message execution where state is
   930  	// implicitly checked by previous tx executions
   931  	tx = newTxCounter(1, 0)
   932  
   933  	txBytes, err = cdc.Marshal(tx)
   934  	require.NoError(t, err)
   935  
   936  	res = app.DeliverTx(abci.RequestDeliverTx{Tx: txBytes})
   937  	require.NotEmpty(t, res.Events)
   938  	require.True(t, res.IsOK(), fmt.Sprintf("%v", res))
   939  
   940  	ctx = app.deliverState.ctx
   941  	store = ctx.KVStore(capKey1)
   942  	require.Equal(t, int64(2), getIntFromStore(store, anteKey))
   943  	require.Equal(t, int64(1), getIntFromStore(store, deliverKey))
   944  
   945  	// commit
   946  	app.EndBlock(abci.RequestEndBlock{})
   947  	app.Commit()
   948  }
   949  
   950  func TestGasConsumptionBadTx(t *testing.T) {
   951  	gasWanted := uint64(5)
   952  	anteOpt := func(bapp *BaseApp) {
   953  		bapp.SetAnteHandler(func(ctx sdk.Context, tx sdk.Tx, simulate bool) (newCtx sdk.Context, err error) {
   954  			newCtx = ctx.WithGasMeter(sdk.NewGasMeter(gasWanted))
   955  
   956  			defer func() {
   957  				if r := recover(); r != nil {
   958  					switch rType := r.(type) {
   959  					case sdk.ErrorOutOfGas:
   960  						log := fmt.Sprintf("out of gas in location: %v", rType.Descriptor)
   961  						err = sdkerrors.Wrap(sdkerrors.ErrOutOfGas, log)
   962  					default:
   963  						panic(r)
   964  					}
   965  				}
   966  			}()
   967  
   968  			txTest := tx.(*txTest)
   969  			newCtx.GasMeter().ConsumeGas(uint64(txTest.Counter), "counter-ante")
   970  			if txTest.FailOnAnte {
   971  				return newCtx, sdkerrors.Wrap(sdkerrors.ErrUnauthorized, "ante handler failure")
   972  			}
   973  
   974  			return
   975  		})
   976  	}
   977  
   978  	routerOpt := func(bapp *BaseApp) {
   979  		r := sdk.NewRoute(routeMsgCounter, func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) {
   980  			count := msg.(*msgCounter).Counter
   981  			ctx.GasMeter().ConsumeGas(uint64(count), "counter-handler")
   982  			return &sdk.Result{}, nil
   983  		})
   984  		bapp.Router().AddRoute(r)
   985  	}
   986  
   987  	cdc := codec.NewLegacyAmino()
   988  	registerTestCodec(cdc)
   989  
   990  	app := setupBaseApp(t, anteOpt, routerOpt)
   991  	app.InitChain(abci.RequestInitChain{
   992  		ConsensusParams: &abci.ConsensusParams{
   993  			Block: &abci.BlockParams{
   994  				MaxGas: 9,
   995  			},
   996  		},
   997  	})
   998  
   999  	app.InitChain(abci.RequestInitChain{})
  1000  
  1001  	header := tmproto.Header{Height: app.LastBlockHeight() + 1}
  1002  	app.BeginBlock(ocabci.RequestBeginBlock{Header: header})
  1003  
  1004  	tx := newTxCounter(5, 0)
  1005  	tx.setFailOnAnte(true)
  1006  	txBytes, err := cdc.Marshal(tx)
  1007  	require.NoError(t, err)
  1008  
  1009  	res := app.DeliverTx(abci.RequestDeliverTx{Tx: txBytes})
  1010  	require.False(t, res.IsOK(), fmt.Sprintf("%v", res))
  1011  
  1012  	// require next tx to fail due to black gas limit
  1013  	tx = newTxCounter(5, 0)
  1014  	txBytes, err = cdc.Marshal(tx)
  1015  	require.NoError(t, err)
  1016  
  1017  	res = app.DeliverTx(abci.RequestDeliverTx{Tx: txBytes})
  1018  	require.False(t, res.IsOK(), fmt.Sprintf("%v", res))
  1019  }
  1020  
  1021  func TestInitChainer(t *testing.T) {
  1022  	name := t.Name()
  1023  	// keep the db and logger ourselves so
  1024  	// we can reload the same  app later
  1025  	db := dbm.NewMemDB()
  1026  	logger := defaultLogger()
  1027  	app := NewBaseApp(name, logger, db, nil)
  1028  	capKey := sdk.NewKVStoreKey("main")
  1029  	capKey2 := sdk.NewKVStoreKey("key2")
  1030  	app.MountStores(capKey, capKey2)
  1031  
  1032  	// set a value in the store on init chain
  1033  	key, value := []byte("hello"), []byte("goodbye")
  1034  	var initChainer sdk.InitChainer = func(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain {
  1035  		store := ctx.KVStore(capKey)
  1036  		store.Set(key, value)
  1037  		return abci.ResponseInitChain{}
  1038  	}
  1039  
  1040  	query := abci.RequestQuery{
  1041  		Path: "/store/main/key",
  1042  		Data: key,
  1043  	}
  1044  
  1045  	// initChainer is nil - nothing happens
  1046  	app.InitChain(abci.RequestInitChain{})
  1047  	res := app.Query(query)
  1048  	require.Equal(t, 0, len(res.Value))
  1049  
  1050  	// set initChainer and try again - should see the value
  1051  	app.SetInitChainer(initChainer)
  1052  
  1053  	// stores are mounted and private members are set - sealing baseapp
  1054  	err := app.LoadLatestVersion() // needed to make stores non-nil
  1055  	require.Nil(t, err)
  1056  	require.Equal(t, int64(0), app.LastBlockHeight())
  1057  
  1058  	initChainRes := app.InitChain(abci.RequestInitChain{AppStateBytes: []byte("{}"), ChainId: "test-chain-id"}) // must have valid JSON genesis file, even if empty
  1059  
  1060  	// The AppHash returned by a new chain is the sha256 hash of "".
  1061  	// $ echo -n '' | sha256sum
  1062  	// e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
  1063  	require.Equal(
  1064  		t,
  1065  		[]byte{0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55},
  1066  		initChainRes.AppHash,
  1067  	)
  1068  
  1069  	// assert that chainID is set correctly in InitChain
  1070  	chainID := app.deliverState.ctx.ChainID()
  1071  	require.Equal(t, "test-chain-id", chainID, "ChainID in deliverState not set correctly in InitChain")
  1072  
  1073  	chainID = app.checkState.ctx.ChainID()
  1074  	require.Equal(t, "test-chain-id", chainID, "ChainID in checkState not set correctly in InitChain")
  1075  
  1076  	app.Commit()
  1077  	res = app.Query(query)
  1078  	require.Equal(t, int64(1), app.LastBlockHeight())
  1079  	require.Equal(t, value, res.Value)
  1080  
  1081  	// reload app
  1082  	app = NewBaseApp(name, logger, db, nil)
  1083  	app.SetInitChainer(initChainer)
  1084  	app.MountStores(capKey, capKey2)
  1085  	err = app.LoadLatestVersion() // needed to make stores non-nil
  1086  	require.Nil(t, err)
  1087  	require.Equal(t, int64(1), app.LastBlockHeight())
  1088  
  1089  	// ensure we can still query after reloading
  1090  	res = app.Query(query)
  1091  	require.Equal(t, value, res.Value)
  1092  
  1093  	// commit and ensure we can still query
  1094  	header := tmproto.Header{Height: app.LastBlockHeight() + 1}
  1095  	app.BeginBlock(ocabci.RequestBeginBlock{Header: header})
  1096  	app.Commit()
  1097  
  1098  	res = app.Query(query)
  1099  	require.Equal(t, value, res.Value)
  1100  }
  1101  
  1102  func TestInitChain_WithInitialHeight(t *testing.T) {
  1103  	name := t.Name()
  1104  	db := dbm.NewMemDB()
  1105  	logger := defaultLogger()
  1106  	app := NewBaseApp(name, logger, db, nil)
  1107  
  1108  	app.InitChain(
  1109  		abci.RequestInitChain{
  1110  			InitialHeight: 3,
  1111  		},
  1112  	)
  1113  	app.Commit()
  1114  
  1115  	require.Equal(t, int64(3), app.LastBlockHeight())
  1116  }
  1117  
  1118  func TestBeginBlock_WithInitialHeight(t *testing.T) {
  1119  	name := t.Name()
  1120  	db := dbm.NewMemDB()
  1121  	logger := defaultLogger()
  1122  	app := NewBaseApp(name, logger, db, nil)
  1123  
  1124  	app.InitChain(
  1125  		abci.RequestInitChain{
  1126  			InitialHeight: 3,
  1127  		},
  1128  	)
  1129  
  1130  	require.PanicsWithError(t, "invalid height: 4; expected: 3", func() {
  1131  		app.BeginBlock(ocabci.RequestBeginBlock{
  1132  			Header: tmproto.Header{
  1133  				Height: 4,
  1134  			},
  1135  		})
  1136  	})
  1137  
  1138  	app.BeginBlock(ocabci.RequestBeginBlock{
  1139  		Header: tmproto.Header{
  1140  			Height: 3,
  1141  		},
  1142  	})
  1143  	app.Commit()
  1144  
  1145  	require.Equal(t, int64(3), app.LastBlockHeight())
  1146  }
  1147  
  1148  // Simple tx with a list of Msgs.
  1149  type txTest struct {
  1150  	Msgs       []sdk.Msg
  1151  	Counter    int64
  1152  	FailOnAnte bool
  1153  }
  1154  
  1155  func (tx *txTest) setFailOnAnte(fail bool) {
  1156  	tx.FailOnAnte = fail
  1157  }
  1158  
  1159  func (tx *txTest) setFailOnHandler(fail bool) {
  1160  	for i, msg := range tx.Msgs {
  1161  		tx.Msgs[i] = msgCounter{msg.(msgCounter).Counter, fail}
  1162  	}
  1163  }
  1164  
  1165  // Implements Tx
  1166  func (tx txTest) GetMsgs() []sdk.Msg   { return tx.Msgs }
  1167  func (tx txTest) ValidateBasic() error { return nil }
  1168  
  1169  const (
  1170  	routeMsgCounter  = "msgCounter"
  1171  	routeMsgCounter2 = "msgCounter2"
  1172  	routeMsgKeyValue = "msgKeyValue"
  1173  )
  1174  
  1175  // ValidateBasic() fails on negative counters.
  1176  // Otherwise it's up to the handlers
  1177  type msgCounter struct {
  1178  	Counter       int64
  1179  	FailOnHandler bool
  1180  }
  1181  
  1182  // dummy implementation of proto.Message
  1183  func (msg msgCounter) Reset()         {}
  1184  func (msg msgCounter) String() string { return "TODO" }
  1185  func (msg msgCounter) ProtoMessage()  {}
  1186  
  1187  // Implements Msg
  1188  func (msg msgCounter) Route() string                { return routeMsgCounter }
  1189  func (msg msgCounter) Type() string                 { return "counter1" }
  1190  func (msg msgCounter) GetSignBytes() []byte         { return nil }
  1191  func (msg msgCounter) GetSigners() []sdk.AccAddress { return nil }
  1192  func (msg msgCounter) ValidateBasic() error {
  1193  	if msg.Counter >= 0 {
  1194  		return nil
  1195  	}
  1196  	return sdkerrors.Wrap(sdkerrors.ErrInvalidSequence, "counter should be a non-negative integer")
  1197  }
  1198  
  1199  func newTxCounter(counter int64, msgCounters ...int64) *txTest {
  1200  	msgs := make([]sdk.Msg, 0, len(msgCounters))
  1201  	for _, c := range msgCounters {
  1202  		msgs = append(msgs, msgCounter{c, false})
  1203  	}
  1204  
  1205  	return &txTest{msgs, counter, false}
  1206  }
  1207  
  1208  // a msg we dont know how to route
  1209  type msgNoRoute struct {
  1210  	msgCounter
  1211  }
  1212  
  1213  func (tx msgNoRoute) Route() string { return "noroute" }
  1214  
  1215  // a msg we dont know how to decode
  1216  type msgNoDecode struct {
  1217  	msgCounter
  1218  }
  1219  
  1220  func (tx msgNoDecode) Route() string { return routeMsgCounter }
  1221  
  1222  // Another counter msg. Duplicate of msgCounter
  1223  type msgCounter2 struct {
  1224  	Counter int64
  1225  }
  1226  
  1227  // dummy implementation of proto.Message
  1228  func (msg msgCounter2) Reset()         {}
  1229  func (msg msgCounter2) String() string { return "TODO" }
  1230  func (msg msgCounter2) ProtoMessage()  {}
  1231  
  1232  // Implements Msg
  1233  func (msg msgCounter2) Route() string                { return routeMsgCounter2 }
  1234  func (msg msgCounter2) Type() string                 { return "counter2" }
  1235  func (msg msgCounter2) GetSignBytes() []byte         { return nil }
  1236  func (msg msgCounter2) GetSigners() []sdk.AccAddress { return nil }
  1237  func (msg msgCounter2) ValidateBasic() error {
  1238  	if msg.Counter >= 0 {
  1239  		return nil
  1240  	}
  1241  	return sdkerrors.Wrap(sdkerrors.ErrInvalidSequence, "counter should be a non-negative integer")
  1242  }
  1243  
  1244  // A msg that sets a key/value pair.
  1245  type msgKeyValue struct {
  1246  	Key   []byte
  1247  	Value []byte
  1248  }
  1249  
  1250  func (msg msgKeyValue) Reset()                       {}
  1251  func (msg msgKeyValue) String() string               { return "TODO" }
  1252  func (msg msgKeyValue) ProtoMessage()                {}
  1253  func (msg msgKeyValue) Route() string                { return routeMsgKeyValue }
  1254  func (msg msgKeyValue) Type() string                 { return "keyValue" }
  1255  func (msg msgKeyValue) GetSignBytes() []byte         { return nil }
  1256  func (msg msgKeyValue) GetSigners() []sdk.AccAddress { return nil }
  1257  func (msg msgKeyValue) ValidateBasic() error {
  1258  	if msg.Key == nil {
  1259  		return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "key cannot be nil")
  1260  	}
  1261  	if msg.Value == nil {
  1262  		return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "value cannot be nil")
  1263  	}
  1264  	return nil
  1265  }
  1266  
  1267  // amino decode
  1268  func testTxDecoder(cdc *codec.LegacyAmino) sdk.TxDecoder {
  1269  	return func(txBytes []byte) (sdk.Tx, error) {
  1270  		var tx txTest
  1271  		if len(txBytes) == 0 {
  1272  			return nil, sdkerrors.Wrap(sdkerrors.ErrTxDecode, "tx bytes are empty")
  1273  		}
  1274  
  1275  		err := cdc.Unmarshal(txBytes, &tx)
  1276  		if err != nil {
  1277  			return nil, sdkerrors.ErrTxDecode
  1278  		}
  1279  
  1280  		return tx, nil
  1281  	}
  1282  }
  1283  
  1284  func anteHandlerTxTest(t *testing.T, capKey sdk.StoreKey, storeKey []byte) sdk.AnteHandler {
  1285  	return func(ctx sdk.Context, tx sdk.Tx, simulate bool) (sdk.Context, error) {
  1286  		store := ctx.KVStore(capKey)
  1287  		txTest := tx.(txTest)
  1288  
  1289  		if txTest.FailOnAnte {
  1290  			return ctx, sdkerrors.Wrap(sdkerrors.ErrUnauthorized, "ante handler failure")
  1291  		}
  1292  
  1293  		_, err := incrementingCounter(t, store, storeKey, txTest.Counter)
  1294  		if err != nil {
  1295  			return ctx, err
  1296  		}
  1297  
  1298  		ctx.EventManager().EmitEvents(
  1299  			counterEvent("ante_handler", txTest.Counter),
  1300  		)
  1301  
  1302  		return ctx, nil
  1303  	}
  1304  }
  1305  
  1306  // TODO(dudong2): remove this func after reverting CheckTx logic
  1307  func anteHandlerTxTest2(t *testing.T, capKey sdk.StoreKey, storeKey []byte) sdk.AnteHandler {
  1308  	return func(ctx sdk.Context, tx sdk.Tx, simulate bool) (sdk.Context, error) {
  1309  		store := ctx.KVStore(capKey)
  1310  		txTest := tx.(*txTest)
  1311  
  1312  		if txTest.FailOnAnte {
  1313  			return ctx, sdkerrors.Wrap(sdkerrors.ErrUnauthorized, "ante handler failure")
  1314  		}
  1315  
  1316  		_, err := incrementingCounter(t, store, storeKey, txTest.Counter)
  1317  		if err != nil {
  1318  			return ctx, err
  1319  		}
  1320  
  1321  		ctx.EventManager().EmitEvents(
  1322  			counterEvent("ante_handler", txTest.Counter),
  1323  		)
  1324  
  1325  		return ctx, nil
  1326  	}
  1327  }
  1328  
  1329  func counterEvent(evType string, msgCount int64) sdk.Events {
  1330  	return sdk.Events{
  1331  		sdk.NewEvent(
  1332  			evType,
  1333  			sdk.NewAttribute("update_counter", fmt.Sprintf("%d", msgCount)),
  1334  		),
  1335  	}
  1336  }
  1337  
  1338  func handlerMsgCounter(t *testing.T, capKey sdk.StoreKey, deliverKey []byte) sdk.Handler {
  1339  	return func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) {
  1340  		ctx = ctx.WithEventManager(sdk.NewEventManager())
  1341  		store := ctx.KVStore(capKey)
  1342  		var msgCount int64
  1343  
  1344  		switch m := msg.(type) {
  1345  		case *msgCounter:
  1346  			if m.FailOnHandler {
  1347  				return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "message handler failure")
  1348  			}
  1349  
  1350  			msgCount = m.Counter
  1351  		case *msgCounter2:
  1352  			msgCount = m.Counter
  1353  		}
  1354  
  1355  		ctx.EventManager().EmitEvents(
  1356  			counterEvent(sdk.EventTypeMessage, msgCount),
  1357  		)
  1358  
  1359  		res, err := incrementingCounter(t, store, deliverKey, msgCount)
  1360  		if err != nil {
  1361  			return nil, err
  1362  		}
  1363  
  1364  		res.Events = ctx.EventManager().Events().ToABCIEvents()
  1365  		return res, nil
  1366  	}
  1367  }
  1368  
  1369  func getIntFromStore(store sdk.KVStore, key []byte) int64 {
  1370  	bz := store.Get(key)
  1371  	if len(bz) == 0 {
  1372  		return 0
  1373  	}
  1374  	i, err := binary.ReadVarint(bytes.NewBuffer(bz))
  1375  	if err != nil {
  1376  		panic(err)
  1377  	}
  1378  	return i
  1379  }
  1380  
  1381  func setIntOnStore(store sdk.KVStore, key []byte, i int64) {
  1382  	bz := make([]byte, 8)
  1383  	n := binary.PutVarint(bz, i)
  1384  	store.Set(key, bz[:n])
  1385  }
  1386  
  1387  // check counter matches what's in store.
  1388  // increment and store
  1389  func incrementingCounter(t *testing.T, store sdk.KVStore, counterKey []byte, counter int64) (*sdk.Result, error) {
  1390  	storedCounter := getIntFromStore(store, counterKey)
  1391  	require.Equal(t, storedCounter, counter)
  1392  	setIntOnStore(store, counterKey, counter+1)
  1393  	return &sdk.Result{}, nil
  1394  }
  1395  
  1396  //---------------------------------------------------------------------
  1397  // Tx processing - CheckTx, DeliverTx, SimulateTx.
  1398  // These tests use the serialized tx as input, while most others will use the
  1399  // Check(), Deliver(), Simulate() methods directly.
  1400  // Ensure that Check/Deliver/Simulate work as expected with the store.
  1401  
  1402  // Test that successive CheckTx can see each others' effects
  1403  // on the store within a block, and that the CheckTx state
  1404  // gets reset to the latest committed state during Commit
  1405  func TestCheckTx(t *testing.T) {
  1406  	// This ante handler reads the key and checks that the value matches the current counter.
  1407  	// This ensures changes to the kvstore persist across successive CheckTx.
  1408  	counterKey := []byte("counter-key")
  1409  
  1410  	anteOpt := func(bapp *BaseApp) { bapp.SetAnteHandler(anteHandlerTxTest2(t, capKey1, counterKey)) }
  1411  	routerOpt := func(bapp *BaseApp) {
  1412  		// TODO: can remove this once CheckTx doesnt process msgs.
  1413  		bapp.Router().AddRoute(sdk.NewRoute(routeMsgCounter, func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) {
  1414  			return &sdk.Result{}, nil
  1415  		}))
  1416  	}
  1417  
  1418  	app := setupBaseApp(t, anteOpt, routerOpt)
  1419  
  1420  	nTxs := int64(5)
  1421  	app.InitChain(abci.RequestInitChain{})
  1422  
  1423  	// Create same codec used in txDecoder
  1424  	codec := codec.NewLegacyAmino()
  1425  	registerTestCodec(codec)
  1426  
  1427  	for i := int64(0); i < nTxs; i++ {
  1428  		tx := newTxCounter(i, 0) // no messages
  1429  		txBytes, err := codec.Marshal(tx)
  1430  		require.NoError(t, err)
  1431  		_, err = app.checkTx(txBytes, tx, false)
  1432  		require.NoError(t, err)
  1433  	}
  1434  
  1435  	checkStateStore := app.checkState.ctx.KVStore(capKey1)
  1436  	storedCounter := getIntFromStore(checkStateStore, counterKey)
  1437  
  1438  	// Ensure AnteHandler ran
  1439  	require.Equal(t, nTxs, storedCounter)
  1440  
  1441  	// If a block is committed, CheckTx state should be reset.
  1442  	header := tmproto.Header{Height: 1}
  1443  	app.BeginBlock(ocabci.RequestBeginBlock{Header: header, Hash: []byte("hash")})
  1444  
  1445  	require.NotNil(t, app.checkState.ctx.BlockGasMeter(), "block gas meter should have been set to checkState")
  1446  	require.NotEmpty(t, app.checkState.ctx.HeaderHash())
  1447  
  1448  	app.EndBlock(abci.RequestEndBlock{})
  1449  	app.Commit()
  1450  
  1451  	// reset CheckTx state
  1452  	app.BeginRecheckTx(ocabci.RequestBeginRecheckTx{Header: header})
  1453  
  1454  	checkStateStore = app.checkState.ctx.KVStore(capKey1)
  1455  	storedBytes := checkStateStore.Get(counterKey)
  1456  	require.Nil(t, storedBytes)
  1457  }
  1458  
  1459  // Test that successive DeliverTx can see each others' effects
  1460  // on the store, both within and across blocks.
  1461  func TestDeliverTx(t *testing.T) {
  1462  	// test increments in the ante
  1463  	anteKey := []byte("ante-key")
  1464  	anteOpt := func(bapp *BaseApp) { bapp.SetAnteHandler(anteHandlerTxTest(t, capKey1, anteKey)) }
  1465  
  1466  	// test increments in the handler
  1467  	deliverKey := []byte("deliver-key")
  1468  	routerOpt := func(bapp *BaseApp) {
  1469  		r := sdk.NewRoute(routeMsgCounter, handlerMsgCounter(t, capKey1, deliverKey))
  1470  		bapp.Router().AddRoute(r)
  1471  	}
  1472  
  1473  	app := setupBaseApp(t, anteOpt, routerOpt)
  1474  	app.InitChain(abci.RequestInitChain{})
  1475  
  1476  	// Create same codec used in txDecoder
  1477  	codec := codec.NewLegacyAmino()
  1478  	registerTestCodec(codec)
  1479  
  1480  	nBlocks := 3
  1481  	txPerHeight := 5
  1482  
  1483  	for blockN := 0; blockN < nBlocks; blockN++ {
  1484  		header := tmproto.Header{Height: int64(blockN) + 1}
  1485  		app.BeginBlock(ocabci.RequestBeginBlock{Header: header})
  1486  
  1487  		for i := 0; i < txPerHeight; i++ {
  1488  			counter := int64(blockN*txPerHeight + i)
  1489  			tx := newTxCounter(counter, counter)
  1490  
  1491  			txBytes, err := codec.Marshal(tx)
  1492  			require.NoError(t, err)
  1493  
  1494  			res := app.DeliverTx(abci.RequestDeliverTx{Tx: txBytes})
  1495  			require.True(t, res.IsOK(), fmt.Sprintf("%v", res))
  1496  			events := res.GetEvents()
  1497  			require.Len(t, events, 3, "should contain ante handler, message type and counter events respectively")
  1498  			require.Equal(t, sdk.MarkEventsToIndex(counterEvent("ante_handler", counter).ToABCIEvents(), map[string]struct{}{})[0], events[0], "ante handler event")
  1499  			require.Equal(t, sdk.MarkEventsToIndex(counterEvent(sdk.EventTypeMessage, counter).ToABCIEvents(), map[string]struct{}{})[0], events[2], "msg handler update counter event")
  1500  		}
  1501  
  1502  		app.EndBlock(abci.RequestEndBlock{})
  1503  		app.Commit()
  1504  	}
  1505  }
  1506  
  1507  func TestOptionFunction(t *testing.T) {
  1508  	logger := defaultLogger()
  1509  	db := dbm.NewMemDB()
  1510  	bap := NewBaseApp("starting name", logger, db, nil, testChangeNameHelper("new name"))
  1511  	require.Equal(t, bap.name, "new name", "BaseApp should have had name changed via option function")
  1512  }
  1513  
  1514  func testChangeNameHelper(name string) func(*BaseApp) {
  1515  	return func(bap *BaseApp) {
  1516  		bap.name = name
  1517  	}
  1518  }
  1519  
  1520  // Test that txs can be unmarshalled and read and that
  1521  // correct error codes are returned when not
  1522  func TestTxDecoder(t *testing.T) {
  1523  	codec := codec.NewLegacyAmino()
  1524  	registerTestCodec(codec)
  1525  
  1526  	app := newBaseApp(t.Name())
  1527  	tx := newTxCounter(1, 0)
  1528  	txBytes := codec.MustMarshal(tx)
  1529  
  1530  	dTx, err := app.txDecoder(txBytes)
  1531  	require.NoError(t, err)
  1532  
  1533  	cTx := dTx.(txTest)
  1534  	require.Equal(t, tx.Counter, cTx.Counter)
  1535  }
  1536  
  1537  // Test that Info returns the latest committed state.
  1538  func TestInfo(t *testing.T) {
  1539  	app := newBaseApp(t.Name())
  1540  
  1541  	// ----- test an empty response -------
  1542  	reqInfo := abci.RequestInfo{}
  1543  	res := app.Info(reqInfo)
  1544  
  1545  	// should be empty
  1546  	assert.Equal(t, "", res.Version)
  1547  	assert.Equal(t, t.Name(), res.GetData())
  1548  	assert.Equal(t, int64(0), res.LastBlockHeight)
  1549  	require.Equal(t, []uint8(nil), res.LastBlockAppHash)
  1550  	require.Equal(t, app.AppVersion(), res.AppVersion)
  1551  	// ----- test a proper response -------
  1552  	// TODO
  1553  }
  1554  
  1555  func TestBaseAppOptionSeal(t *testing.T) {
  1556  	app := setupBaseApp(t)
  1557  
  1558  	require.Panics(t, func() {
  1559  		app.SetName("")
  1560  	})
  1561  	require.Panics(t, func() {
  1562  		app.SetVersion("")
  1563  	})
  1564  	require.Panics(t, func() {
  1565  		app.SetDB(nil)
  1566  	})
  1567  	require.Panics(t, func() {
  1568  		app.SetCMS(nil)
  1569  	})
  1570  	require.Panics(t, func() {
  1571  		app.SetInitChainer(nil)
  1572  	})
  1573  	require.Panics(t, func() {
  1574  		app.SetBeginBlocker(nil)
  1575  	})
  1576  	require.Panics(t, func() {
  1577  		app.SetEndBlocker(nil)
  1578  	})
  1579  	require.Panics(t, func() {
  1580  		app.SetAnteHandler(nil)
  1581  	})
  1582  	require.Panics(t, func() {
  1583  		app.SetAddrPeerFilter(nil)
  1584  	})
  1585  	require.Panics(t, func() {
  1586  		app.SetIDPeerFilter(nil)
  1587  	})
  1588  	require.Panics(t, func() {
  1589  		app.SetFauxMerkleMode()
  1590  	})
  1591  	require.Panics(t, func() {
  1592  		app.SetRouter(NewRouter())
  1593  	})
  1594  }
  1595  
  1596  func TestVersionSetterGetter(t *testing.T) {
  1597  	logger := defaultLogger()
  1598  	pruningOpt := SetPruning(store.PruneDefault)
  1599  	db := dbm.NewMemDB()
  1600  	name := t.Name()
  1601  	app := NewBaseApp(name, logger, db, nil, pruningOpt)
  1602  
  1603  	require.Equal(t, "", app.Version())
  1604  	res := app.Query(abci.RequestQuery{Path: "app/version"})
  1605  	require.True(t, res.IsOK())
  1606  	require.Equal(t, "", string(res.Value))
  1607  
  1608  	versionString := "1.0.0"
  1609  	app.SetVersion(versionString)
  1610  	require.Equal(t, versionString, app.Version())
  1611  	res = app.Query(abci.RequestQuery{Path: "app/version"})
  1612  	require.True(t, res.IsOK())
  1613  	require.Equal(t, versionString, string(res.Value))
  1614  }
  1615  
  1616  func TestLoadVersionInvalid(t *testing.T) {
  1617  	logger := log.NewNopLogger()
  1618  	pruningOpt := SetPruning(store.PruneNothing)
  1619  	db := dbm.NewMemDB()
  1620  	name := t.Name()
  1621  	app := NewBaseApp(name, logger, db, nil, pruningOpt)
  1622  
  1623  	err := app.LoadLatestVersion()
  1624  	require.Nil(t, err)
  1625  
  1626  	// require error when loading an invalid version
  1627  	err = app.LoadVersion(-1)
  1628  	require.Error(t, err)
  1629  
  1630  	header := tmproto.Header{Height: 1}
  1631  	app.BeginBlock(ocabci.RequestBeginBlock{Header: header})
  1632  	res := app.Commit()
  1633  	commitID1 := sdk.CommitID{Version: 1, Hash: res.Data}
  1634  
  1635  	// create a new app with the stores mounted under the same cap key
  1636  	app = NewBaseApp(name, logger, db, nil, pruningOpt)
  1637  
  1638  	// require we can load the latest version
  1639  	err = app.LoadVersion(1)
  1640  	require.Nil(t, err)
  1641  	testLoadVersionHelper(t, app, int64(1), commitID1)
  1642  
  1643  	// require error when loading an invalid version
  1644  	err = app.LoadVersion(2)
  1645  	require.Error(t, err)
  1646  }
  1647  
  1648  // simple one store baseapp with data and snapshots. Each tx is 1 MB in size (uncompressed).
  1649  func setupBaseAppWithSnapshots(t *testing.T, blocks uint, blockTxs int, options ...func(*BaseApp)) (*BaseApp, func()) {
  1650  	codec := codec.NewLegacyAmino()
  1651  	registerTestCodec(codec)
  1652  	routerOpt := func(bapp *BaseApp) {
  1653  		bapp.Router().AddRoute(sdk.NewRoute(routeMsgKeyValue, func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) {
  1654  			kv := msg.(*msgKeyValue)
  1655  			bapp.cms.GetCommitKVStore(capKey2).Set(kv.Key, kv.Value)
  1656  			return &sdk.Result{}, nil
  1657  		}))
  1658  	}
  1659  
  1660  	snapshotInterval := uint64(2)
  1661  	snapshotTimeout := 1 * time.Minute
  1662  	snapshotDir, err := os.MkdirTemp("", "baseapp")
  1663  	require.NoError(t, err)
  1664  	snapshotStore, err := snapshots.NewStore(dbm.NewMemDB(), snapshotDir)
  1665  	require.NoError(t, err)
  1666  	teardown := func() {
  1667  		os.RemoveAll(snapshotDir)
  1668  	}
  1669  
  1670  	app := setupBaseApp(t, append(options,
  1671  		SetSnapshotStore(snapshotStore),
  1672  		SetSnapshotInterval(snapshotInterval),
  1673  		SetPruning(sdk.PruningOptions{KeepEvery: 1}),
  1674  		routerOpt)...)
  1675  
  1676  	app.InitChain(abci.RequestInitChain{})
  1677  
  1678  	r := rand.New(rand.NewSource(3920758213583))
  1679  	keyCounter := 0
  1680  	for height := int64(1); height <= int64(blocks); height++ {
  1681  		app.BeginBlock(ocabci.RequestBeginBlock{Header: tmproto.Header{Height: height}})
  1682  		for txNum := 0; txNum < blockTxs; txNum++ {
  1683  			tx := txTest{Msgs: []sdk.Msg{}}
  1684  			for msgNum := 0; msgNum < 100; msgNum++ {
  1685  				key := []byte(fmt.Sprintf("%v", keyCounter))
  1686  				value := make([]byte, 10000)
  1687  				_, err := r.Read(value)
  1688  				require.NoError(t, err)
  1689  				tx.Msgs = append(tx.Msgs, msgKeyValue{Key: key, Value: value})
  1690  				keyCounter++
  1691  			}
  1692  			txBytes, err := codec.Marshal(tx)
  1693  			require.NoError(t, err)
  1694  			resp := app.DeliverTx(abci.RequestDeliverTx{Tx: txBytes})
  1695  			require.True(t, resp.IsOK(), "%v", resp.String())
  1696  		}
  1697  		app.EndBlock(abci.RequestEndBlock{Height: height})
  1698  		app.Commit()
  1699  
  1700  		// Wait for snapshot to be taken, since it happens asynchronously.
  1701  		if uint64(height)%snapshotInterval == 0 {
  1702  			start := time.Now()
  1703  			for {
  1704  				if time.Since(start) > snapshotTimeout {
  1705  					t.Errorf("timed out waiting for snapshot after %v", snapshotTimeout)
  1706  				}
  1707  				snapshot, err := snapshotStore.Get(uint64(height), snapshottypes.CurrentFormat)
  1708  				require.NoError(t, err)
  1709  				if snapshot != nil {
  1710  					break
  1711  				}
  1712  				time.Sleep(100 * time.Millisecond)
  1713  			}
  1714  		}
  1715  	}
  1716  
  1717  	return app, teardown
  1718  }
  1719  
  1720  func TestMountStores(t *testing.T) {
  1721  	app := setupBaseApp(t)
  1722  
  1723  	// check both stores
  1724  	store1 := app.cms.GetCommitKVStore(capKey1)
  1725  	require.NotNil(t, store1)
  1726  	store2 := app.cms.GetCommitKVStore(capKey2)
  1727  	require.NotNil(t, store2)
  1728  }
  1729  
  1730  // Test that we can make commits and then reload old versions.
  1731  // Test that LoadLatestVersion actually does.
  1732  func TestLoadVersion(t *testing.T) {
  1733  	logger := defaultLogger()
  1734  	pruningOpt := SetPruning(store.PruneNothing)
  1735  	db := dbm.NewMemDB()
  1736  	name := t.Name()
  1737  	app := NewBaseApp(name, logger, db, nil, pruningOpt)
  1738  
  1739  	// make a cap key and mount the store
  1740  	err := app.LoadLatestVersion() // needed to make stores non-nil
  1741  	require.Nil(t, err)
  1742  
  1743  	emptyCommitID := sdk.CommitID{}
  1744  
  1745  	// fresh store has zero/empty last commit
  1746  	lastHeight := app.LastBlockHeight()
  1747  	lastID := app.LastCommitID()
  1748  	require.Equal(t, int64(0), lastHeight)
  1749  	require.Equal(t, emptyCommitID, lastID)
  1750  
  1751  	// execute a block, collect commit ID
  1752  	header := tmproto.Header{Height: 1}
  1753  	app.BeginBlock(ocabci.RequestBeginBlock{Header: header})
  1754  	res := app.Commit()
  1755  	commitID1 := sdk.CommitID{Version: 1, Hash: res.Data}
  1756  
  1757  	// execute a block, collect commit ID
  1758  	header = tmproto.Header{Height: 2}
  1759  	app.BeginBlock(ocabci.RequestBeginBlock{Header: header})
  1760  	res = app.Commit()
  1761  	commitID2 := sdk.CommitID{Version: 2, Hash: res.Data}
  1762  
  1763  	// reload with LoadLatestVersion
  1764  	app = NewBaseApp(name, logger, db, nil, pruningOpt)
  1765  	app.MountStores()
  1766  	err = app.LoadLatestVersion()
  1767  	require.Nil(t, err)
  1768  	testLoadVersionHelper(t, app, int64(2), commitID2)
  1769  
  1770  	// reload with LoadVersion, see if you can commit the same block and get
  1771  	// the same result
  1772  	app = NewBaseApp(name, logger, db, nil, pruningOpt)
  1773  	err = app.LoadVersion(1)
  1774  	require.Nil(t, err)
  1775  	testLoadVersionHelper(t, app, int64(1), commitID1)
  1776  	app.BeginBlock(ocabci.RequestBeginBlock{Header: header})
  1777  	app.Commit()
  1778  	testLoadVersionHelper(t, app, int64(2), commitID2)
  1779  }
  1780  
  1781  func useDefaultLoader(app *BaseApp) {
  1782  	app.SetStoreLoader(DefaultStoreLoader)
  1783  }
  1784  
  1785  func initStore(t *testing.T, db dbm.DB, storeKey string, k, v []byte) {
  1786  	rs := rootmulti.NewStore(db, log.NewNopLogger())
  1787  	rs.SetPruning(store.PruneNothing)
  1788  	key := sdk.NewKVStoreKey(storeKey)
  1789  	rs.MountStoreWithDB(key, store.StoreTypeIAVL, nil)
  1790  	err := rs.LoadLatestVersion()
  1791  	require.Nil(t, err)
  1792  	require.Equal(t, int64(0), rs.LastCommitID().Version)
  1793  
  1794  	// write some data in substore
  1795  	kv, _ := rs.GetStore(key).(store.KVStore)
  1796  	require.NotNil(t, kv)
  1797  	kv.Set(k, v)
  1798  	commitID := rs.Commit()
  1799  	require.Equal(t, int64(1), commitID.Version)
  1800  }
  1801  
  1802  func checkStore(t *testing.T, db dbm.DB, ver int64, storeKey string, k, v []byte) {
  1803  	rs := rootmulti.NewStore(db, log.NewNopLogger())
  1804  	rs.SetPruning(store.PruneDefault)
  1805  	key := sdk.NewKVStoreKey(storeKey)
  1806  	rs.MountStoreWithDB(key, store.StoreTypeIAVL, nil)
  1807  	err := rs.LoadLatestVersion()
  1808  	require.Nil(t, err)
  1809  	require.Equal(t, ver, rs.LastCommitID().Version)
  1810  
  1811  	// query data in substore
  1812  	kv, _ := rs.GetStore(key).(store.KVStore)
  1813  	require.NotNil(t, kv)
  1814  	require.Equal(t, v, kv.Get(k))
  1815  }
  1816  
  1817  // Test that we can make commits and then reload old versions.
  1818  // Test that LoadLatestVersion actually does.
  1819  func TestSetLoader(t *testing.T) {
  1820  	cases := map[string]struct {
  1821  		setLoader    func(*BaseApp)
  1822  		origStoreKey string
  1823  		loadStoreKey string
  1824  	}{
  1825  		"don't set loader": {
  1826  			origStoreKey: "foo",
  1827  			loadStoreKey: "foo",
  1828  		},
  1829  		"default loader": {
  1830  			setLoader:    useDefaultLoader,
  1831  			origStoreKey: "foo",
  1832  			loadStoreKey: "foo",
  1833  		},
  1834  	}
  1835  
  1836  	k := []byte("key")
  1837  	v := []byte("value")
  1838  
  1839  	for name, tc := range cases {
  1840  		tc := tc
  1841  		t.Run(name, func(t *testing.T) {
  1842  			// prepare a db with some data
  1843  			db := dbm.NewMemDB()
  1844  			initStore(t, db, tc.origStoreKey, k, v)
  1845  
  1846  			// load the app with the existing db
  1847  			opts := []func(*BaseApp){SetPruning(store.PruneNothing)}
  1848  			if tc.setLoader != nil {
  1849  				opts = append(opts, tc.setLoader)
  1850  			}
  1851  			app := NewBaseApp(t.Name(), defaultLogger(), db, nil, opts...)
  1852  			app.MountStores(sdk.NewKVStoreKey(tc.loadStoreKey))
  1853  			err := app.LoadLatestVersion()
  1854  			require.Nil(t, err)
  1855  
  1856  			// "execute" one block
  1857  			app.BeginBlock(ocabci.RequestBeginBlock{Header: tmproto.Header{Height: 2}})
  1858  			res := app.Commit()
  1859  			require.NotNil(t, res.Data)
  1860  
  1861  			// check db is properly updated
  1862  			checkStore(t, db, 2, tc.loadStoreKey, k, v)
  1863  			checkStore(t, db, 2, tc.loadStoreKey, []byte("foo"), nil)
  1864  		})
  1865  	}
  1866  }