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

     1  package baseapp
     2  
     3  import (
     4  	"encoding/json"
     5  	"os"
     6  	"testing"
     7  
     8  	"github.com/golang/mock/gomock"
     9  	"github.com/stretchr/testify/assert"
    10  	"github.com/stretchr/testify/require"
    11  	abci "github.com/tendermint/tendermint/abci/types"
    12  	tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
    13  	dbm "github.com/tendermint/tm-db"
    14  
    15  	ocabci "github.com/Finschia/ostracon/abci/types"
    16  	"github.com/Finschia/ostracon/libs/log"
    17  
    18  	"github.com/Finschia/finschia-sdk/codec"
    19  	"github.com/Finschia/finschia-sdk/codec/legacy"
    20  	"github.com/Finschia/finschia-sdk/server/config"
    21  	"github.com/Finschia/finschia-sdk/snapshots"
    22  	store "github.com/Finschia/finschia-sdk/store/types"
    23  	sdk "github.com/Finschia/finschia-sdk/types"
    24  	"github.com/Finschia/finschia-sdk/x/auth/legacy/legacytx"
    25  )
    26  
    27  var (
    28  	capKey1 = sdk.NewKVStoreKey("key1")
    29  	capKey2 = sdk.NewKVStoreKey("key2")
    30  )
    31  
    32  func defaultLogger() log.Logger {
    33  	return log.NewOCLogger(log.NewSyncWriter(os.Stdout)).With("module", "sdk/app")
    34  }
    35  
    36  func newBaseApp(name string, options ...func(*BaseApp)) *BaseApp {
    37  	logger := defaultLogger()
    38  	db := dbm.NewMemDB()
    39  	codec := codec.NewLegacyAmino()
    40  	registerTestCodec(codec)
    41  	return NewBaseApp(name, logger, db, testTxDecoder(codec), options...)
    42  }
    43  
    44  func registerTestCodec(cdc *codec.LegacyAmino) {
    45  	// register Tx, Msg
    46  	sdk.RegisterLegacyAminoCodec(cdc)
    47  
    48  	// register test types
    49  	cdc.RegisterConcrete(&txTest{}, "cosmos-sdk/baseapp/txTest", nil)
    50  	legacy.RegisterAminoMsg(cdc, &msgCounter{}, "cosmos-sdk/baseapp/msgCounter")
    51  	legacy.RegisterAminoMsg(cdc, &msgCounter2{}, "cosmos-sdk/baseapp/msgCounter2")
    52  	legacy.RegisterAminoMsg(cdc, &msgKeyValue{}, "cosmos-sdk/baseapp/msgKeyValue")
    53  	legacy.RegisterAminoMsg(cdc, &msgNoRoute{}, "cosmos-sdk/baseapp/msgNoRoute")
    54  }
    55  
    56  // aminoTxEncoder creates a amino TxEncoder for testing purposes.
    57  func aminoTxEncoder() sdk.TxEncoder {
    58  	cdc := codec.NewLegacyAmino()
    59  	registerTestCodec(cdc)
    60  
    61  	return legacytx.StdTxConfig{Cdc: cdc}.TxEncoder()
    62  }
    63  
    64  // simple one store baseapp
    65  func setupBaseApp(t *testing.T, options ...func(*BaseApp)) *BaseApp {
    66  	app := newBaseApp(t.Name(), options...)
    67  	require.Equal(t, t.Name(), app.Name())
    68  
    69  	app.MountStores(capKey1, capKey2)
    70  	app.SetParamStore(&paramStore{db: dbm.NewMemDB()})
    71  
    72  	// stores are mounted
    73  	err := app.LoadLatestVersion()
    74  	require.Nil(t, err)
    75  	return app
    76  }
    77  
    78  func TestLoadVersionPruning(t *testing.T) {
    79  	logger := log.NewNopLogger()
    80  	pruningOptions := store.PruningOptions{
    81  		KeepRecent: 2,
    82  		KeepEvery:  3,
    83  		Interval:   1,
    84  	}
    85  	pruningOpt := SetPruning(pruningOptions)
    86  	db := dbm.NewMemDB()
    87  	name := t.Name()
    88  	app := NewBaseApp(name, logger, db, nil, pruningOpt)
    89  
    90  	// make a cap key and mount the store
    91  	capKey := sdk.NewKVStoreKey("key1")
    92  	app.MountStores(capKey)
    93  
    94  	err := app.LoadLatestVersion() // needed to make stores non-nil
    95  	require.Nil(t, err)
    96  
    97  	emptyCommitID := sdk.CommitID{}
    98  
    99  	// fresh store has zero/empty last commit
   100  	lastHeight := app.LastBlockHeight()
   101  	lastID := app.LastCommitID()
   102  	require.Equal(t, int64(0), lastHeight)
   103  	require.Equal(t, emptyCommitID, lastID)
   104  
   105  	var lastCommitID sdk.CommitID
   106  
   107  	// Commit seven blocks, of which 7 (latest) is kept in addition to 6, 5
   108  	// (keep recent) and 3 (keep every).
   109  	for i := int64(1); i <= 7; i++ {
   110  		app.BeginBlock(ocabci.RequestBeginBlock{Header: tmproto.Header{Height: i}})
   111  		res := app.Commit()
   112  		lastCommitID = sdk.CommitID{Version: i, Hash: res.Data}
   113  	}
   114  
   115  	for _, v := range []int64{1, 2, 4} {
   116  		_, err = app.cms.CacheMultiStoreWithVersion(v)
   117  		require.NoError(t, err)
   118  	}
   119  
   120  	for _, v := range []int64{3, 5, 6, 7} {
   121  		_, err = app.cms.CacheMultiStoreWithVersion(v)
   122  		require.NoError(t, err)
   123  	}
   124  
   125  	// reload with LoadLatestVersion, check it loads last version
   126  	app = NewBaseApp(name, logger, db, nil, pruningOpt)
   127  	app.MountStores(capKey)
   128  
   129  	err = app.LoadLatestVersion()
   130  	require.Nil(t, err)
   131  	testLoadVersionHelper(t, app, int64(7), lastCommitID)
   132  }
   133  
   134  func testLoadVersionHelper(t *testing.T, app *BaseApp, expectedHeight int64, expectedID sdk.CommitID) {
   135  	lastHeight := app.LastBlockHeight()
   136  	lastID := app.LastCommitID()
   137  	require.Equal(t, expectedHeight, lastHeight)
   138  	require.Equal(t, expectedID, lastID)
   139  }
   140  
   141  func TestSetMinGasPrices(t *testing.T) {
   142  	minGasPrices := sdk.DecCoins{sdk.NewInt64DecCoin("stake", 5000)}
   143  	app := newBaseApp(t.Name(), SetMinGasPrices(minGasPrices.String()))
   144  	require.Equal(t, minGasPrices, app.minGasPrices)
   145  }
   146  
   147  func TestGetMaximumBlockGas(t *testing.T) {
   148  	app := setupBaseApp(t)
   149  	app.InitChain(abci.RequestInitChain{})
   150  	ctx := app.NewContext(true, tmproto.Header{})
   151  
   152  	app.StoreConsensusParams(ctx, &abci.ConsensusParams{Block: &abci.BlockParams{MaxGas: 0}})
   153  	require.Equal(t, uint64(0), app.getMaximumBlockGas(ctx))
   154  
   155  	app.StoreConsensusParams(ctx, &abci.ConsensusParams{Block: &abci.BlockParams{MaxGas: -1}})
   156  	require.Equal(t, uint64(0), app.getMaximumBlockGas(ctx))
   157  
   158  	app.StoreConsensusParams(ctx, &abci.ConsensusParams{Block: &abci.BlockParams{MaxGas: 5000000}})
   159  	require.Equal(t, uint64(5000000), app.getMaximumBlockGas(ctx))
   160  
   161  	app.StoreConsensusParams(ctx, &abci.ConsensusParams{Block: &abci.BlockParams{MaxGas: -5000000}})
   162  	require.Panics(t, func() { app.getMaximumBlockGas(ctx) })
   163  }
   164  
   165  func TestListSnapshots(t *testing.T) {
   166  	type setupConfig struct {
   167  		blocks            uint64
   168  		blockTxs          int
   169  		snapshotInterval  uint64
   170  		snapshotKeepEvery uint32
   171  	}
   172  
   173  	app, _ := setupBaseAppWithSnapshots(t, 2, 5)
   174  
   175  	expected := abci.ResponseListSnapshots{Snapshots: []*abci.Snapshot{
   176  		{Height: 2, Format: 1, Chunks: 2},
   177  	}}
   178  
   179  	resp := app.ListSnapshots(abci.RequestListSnapshots{})
   180  	queryResponse := app.Query(abci.RequestQuery{
   181  		Path: "/app/snapshots",
   182  	})
   183  
   184  	queryListSnapshotsResp := abci.ResponseListSnapshots{}
   185  	err := json.Unmarshal(queryResponse.Value, &queryListSnapshotsResp)
   186  	require.NoError(t, err)
   187  
   188  	for i, s := range resp.Snapshots {
   189  		querySnapshot := queryListSnapshotsResp.Snapshots[i]
   190  		// we check that the query snapshot and function snapshot are equal
   191  		// Then we check that the hash and metadata are not empty. We atm
   192  		// do not have a good way to generate the expected value for these.
   193  		assert.Equal(t, *s, *querySnapshot)
   194  		assert.NotEmpty(t, s.Hash)
   195  		assert.NotEmpty(t, s.Metadata)
   196  		// Set hash and metadata to nil, so we can check the other snapshot
   197  		// fields against expected
   198  		s.Hash = nil
   199  		s.Metadata = nil
   200  	}
   201  	assert.Equal(t, expected, resp)
   202  }
   203  
   204  func TestSnapshotManager(t *testing.T) {
   205  	app := newBaseApp(t.Name())
   206  	require.Nil(t, app.SnapshotManager())
   207  
   208  	tempDir := t.TempDir()
   209  	snapshotDB, err := sdk.NewLevelDB("metadata", tempDir)
   210  	if err != nil {
   211  		require.NoError(t, err)
   212  	}
   213  	snapshotStore, err := snapshots.NewStore(snapshotDB, tempDir)
   214  	if err != nil {
   215  		require.NoError(t, err)
   216  	}
   217  	app.SetSnapshotStore(snapshotStore)
   218  	require.NotNil(t, app.SnapshotManager())
   219  }
   220  
   221  func TestSetChanCheckTxSize(t *testing.T) {
   222  	logger := defaultLogger()
   223  	db := dbm.NewMemDB()
   224  
   225  	var size = uint(100)
   226  
   227  	app := NewBaseApp(t.Name(), logger, db, nil, SetChanCheckTxSize(size))
   228  	require.Equal(t, int(size), cap(app.chCheckTx))
   229  
   230  	app = NewBaseApp(t.Name(), logger, db, nil)
   231  	require.Equal(t, config.DefaultChanCheckTxSize, cap(app.chCheckTx))
   232  }
   233  
   234  func TestCreateEvents(t *testing.T) {
   235  	testCases := map[string]struct {
   236  		eventsIn    sdk.Events
   237  		messageName string
   238  		eventsOut   sdk.Events
   239  	}{
   240  		"cosmos": {
   241  			messageName: "cosmos.foo.v1beta1.MsgFoo",
   242  			eventsOut:   sdk.Events{{Type: "message", Attributes: []abci.EventAttribute{{Key: []uint8{0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e}, Value: []uint8{0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x66, 0x6f, 0x6f, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x46, 0x6f, 0x6f}, Index: false}, {Key: []uint8{0x73, 0x65, 0x6e, 0x64, 0x65, 0x72}, Value: []uint8{0x6c, 0x69, 0x6e, 0x6b, 0x31, 0x76, 0x33, 0x6a, 0x6b, 0x7a, 0x65, 0x72, 0x7a, 0x76, 0x34, 0x6a, 0x6b, 0x76, 0x6b, 0x75, 0x64, 0x32, 0x63, 0x6d}, Index: false}, {Key: []uint8{0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65}, Value: []uint8{0x66, 0x6f, 0x6f}, Index: false}}}},
   243  		},
   244  		"ibc without module attribute": {
   245  			messageName: "ibc.foo.bar.v1.MsgBar",
   246  			eventsOut:   sdk.Events{{Type: "message", Attributes: []abci.EventAttribute{{Key: []uint8{0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e}, Value: []uint8{0x2f, 0x69, 0x62, 0x63, 0x2e, 0x66, 0x6f, 0x6f, 0x2e, 0x62, 0x61, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x42, 0x61, 0x72}, Index: false}, {Key: []uint8{0x73, 0x65, 0x6e, 0x64, 0x65, 0x72}, Value: []uint8{0x6c, 0x69, 0x6e, 0x6b, 0x31, 0x76, 0x33, 0x6a, 0x6b, 0x7a, 0x65, 0x72, 0x7a, 0x76, 0x34, 0x6a, 0x6b, 0x76, 0x6b, 0x75, 0x64, 0x32, 0x63, 0x6d}, Index: false}}}},
   247  		},
   248  		"ibc with module attribute": {
   249  			eventsIn:    sdk.Events{{Type: "message", Attributes: []abci.EventAttribute{{Key: []uint8{0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65}, Value: []uint8{0x66, 0x6f, 0x6f, 0x53, 0x62, 0x61, 0x72}, Index: false}}}},
   250  			messageName: "ibc.foo.bar.v1.MsgBar",
   251  			eventsOut:   sdk.Events{{Type: "message", Attributes: []abci.EventAttribute{{Key: []uint8{0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e}, Value: []uint8{0x2f, 0x69, 0x62, 0x63, 0x2e, 0x66, 0x6f, 0x6f, 0x2e, 0x62, 0x61, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x42, 0x61, 0x72}, Index: false}, {Key: []uint8{0x73, 0x65, 0x6e, 0x64, 0x65, 0x72}, Value: []uint8{0x6c, 0x69, 0x6e, 0x6b, 0x31, 0x76, 0x33, 0x6a, 0x6b, 0x7a, 0x65, 0x72, 0x7a, 0x76, 0x34, 0x6a, 0x6b, 0x76, 0x6b, 0x75, 0x64, 0x32, 0x63, 0x6d}, Index: false}}}, {Type: "message", Attributes: []abci.EventAttribute{{Key: []uint8{0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65}, Value: []uint8{0x66, 0x6f, 0x6f, 0x53, 0x62, 0x61, 0x72}, Index: false}}}},
   252  		},
   253  	}
   254  
   255  	for name, tc := range testCases {
   256  		t.Run(name, func(t *testing.T) {
   257  			ctrl := gomock.NewController(t)
   258  			msg := NewMockXXXMessage(ctrl)
   259  
   260  			signer := sdk.AccAddress([]byte("deadbeef"))
   261  			msg.
   262  				EXPECT().
   263  				GetSigners().
   264  				Return([]sdk.AccAddress{signer}).
   265  				AnyTimes()
   266  			msg.
   267  				EXPECT().
   268  				XXX_MessageName().
   269  				Return(tc.messageName).
   270  				AnyTimes()
   271  
   272  			eventsOut := createEvents(tc.eventsIn, msg)
   273  			require.Equal(t, tc.eventsOut, eventsOut)
   274  		})
   275  	}
   276  }