github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/cosmos-sdk/x/bank/app_test.go (about)

     1  package bank_test
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/stretchr/testify/require"
     7  
     8  	abci "github.com/fibonacci-chain/fbc/libs/tendermint/abci/types"
     9  	"github.com/fibonacci-chain/fbc/libs/tendermint/crypto"
    10  	"github.com/fibonacci-chain/fbc/libs/tendermint/crypto/secp256k1"
    11  
    12  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/simapp"
    13  	sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types"
    14  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/auth"
    15  	authexported "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/auth/exported"
    16  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/bank/internal/types"
    17  )
    18  
    19  type (
    20  	expectedBalance struct {
    21  		addr  sdk.AccAddress
    22  		coins sdk.Coins
    23  	}
    24  
    25  	appTestCase struct {
    26  		expSimPass       bool
    27  		expPass          bool
    28  		msgs             []sdk.Msg
    29  		accNums          []uint64
    30  		accSeqs          []uint64
    31  		privKeys         []crypto.PrivKey
    32  		expectedBalances []expectedBalance
    33  	}
    34  )
    35  
    36  var (
    37  	priv1 = secp256k1.GenPrivKey()
    38  	addr1 = sdk.AccAddress(priv1.PubKey().Address())
    39  	priv2 = secp256k1.GenPrivKey()
    40  	addr2 = sdk.AccAddress(priv2.PubKey().Address())
    41  	addr3 = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address())
    42  	priv4 = secp256k1.GenPrivKey()
    43  	addr4 = sdk.AccAddress(priv4.PubKey().Address())
    44  
    45  	coins     = sdk.Coins{sdk.NewInt64Coin("foocoin", 10)}
    46  	halfCoins = sdk.Coins{sdk.NewInt64Coin("foocoin", 5)}
    47  
    48  	sendMsg1 = types.NewMsgSend(addr1, addr2, coins)
    49  
    50  	multiSendMsg1 = types.MsgMultiSend{
    51  		Inputs:  []types.Input{types.NewInput(addr1, coins)},
    52  		Outputs: []types.Output{types.NewOutput(addr2, coins)},
    53  	}
    54  	multiSendMsg2 = types.MsgMultiSend{
    55  		Inputs: []types.Input{types.NewInput(addr1, coins)},
    56  		Outputs: []types.Output{
    57  			types.NewOutput(addr2, halfCoins),
    58  			types.NewOutput(addr3, halfCoins),
    59  		},
    60  	}
    61  	multiSendMsg3 = types.MsgMultiSend{
    62  		Inputs: []types.Input{
    63  			types.NewInput(addr1, coins),
    64  			types.NewInput(addr4, coins),
    65  		},
    66  		Outputs: []types.Output{
    67  			types.NewOutput(addr2, coins),
    68  			types.NewOutput(addr3, coins),
    69  		},
    70  	}
    71  	multiSendMsg4 = types.MsgMultiSend{
    72  		Inputs: []types.Input{
    73  			types.NewInput(addr2, coins),
    74  		},
    75  		Outputs: []types.Output{
    76  			types.NewOutput(addr1, coins),
    77  		},
    78  	}
    79  	multiSendMsg5 = types.MsgMultiSend{
    80  		Inputs: []types.Input{
    81  			types.NewInput(addr1, coins),
    82  		},
    83  		Outputs: []types.Output{
    84  			types.NewOutput(moduleAccAddr, coins),
    85  		},
    86  	}
    87  )
    88  
    89  func TestSendNotEnoughBalance(t *testing.T) {
    90  	acc := &auth.BaseAccount{
    91  		Address: addr1,
    92  		Coins:   sdk.Coins{sdk.NewInt64Coin("foocoin", 67)},
    93  	}
    94  
    95  	genAccs := []authexported.GenesisAccount{acc}
    96  	app := simapp.SetupWithGenesisAccounts(genAccs)
    97  
    98  	ctxCheck := app.BaseApp.NewContext(true, abci.Header{})
    99  
   100  	res1 := app.AccountKeeper.GetAccount(ctxCheck, addr1)
   101  	require.NotNil(t, res1)
   102  	require.Equal(t, acc, res1.(*auth.BaseAccount))
   103  
   104  	origAccNum := res1.GetAccountNumber()
   105  	origSeq := res1.GetSequence()
   106  
   107  	sendMsg := types.NewMsgSend(addr1, addr2, sdk.Coins{sdk.NewInt64Coin("foocoin", 100)})
   108  	header := abci.Header{Height: app.LastBlockHeight() + 1}
   109  	simapp.SignCheckDeliver(t, app.Codec(), app.BaseApp, header, []sdk.Msg{sendMsg}, []uint64{origAccNum}, []uint64{origSeq}, false, false, priv1)
   110  
   111  	simapp.CheckBalance(t, app, addr1, sdk.Coins{sdk.NewInt64Coin("foocoin", 67)})
   112  
   113  	res2 := app.AccountKeeper.GetAccount(app.NewContext(true, abci.Header{}), addr1)
   114  	require.NotNil(t, res2)
   115  
   116  	require.Equal(t, res2.GetAccountNumber(), origAccNum)
   117  	require.Equal(t, res2.GetSequence(), origSeq+1)
   118  }
   119  
   120  // A module account cannot be the recipient of bank sends unless it has been marked as such
   121  func TestSendToModuleAcc(t *testing.T) {
   122  	tests := []struct {
   123  		name           string
   124  		fromBalance    sdk.Coins
   125  		msg            types.MsgSend
   126  		expSimPass     bool
   127  		expPass        bool
   128  		expFromBalance sdk.Coins
   129  		expToBalance   sdk.Coins
   130  	}{
   131  		{
   132  			name:           "Normal module account cannot be the recipient of bank sends",
   133  			fromBalance:    coins,
   134  			msg:            types.NewMsgSend(addr1, moduleAccAddr, coins),
   135  			expSimPass:     false,
   136  			expPass:        false,
   137  			expFromBalance: coins,
   138  			expToBalance:   sdk.NewCoins(),
   139  		},
   140  		//{
   141  		//	name:           "Allowed module account can be the recipient of bank sends",
   142  		//	fromBalance:    coins,
   143  		//	msg:            types.NewMsgSend(addr1, supply.NewModuleAddress(distribution.ModuleName), coins),
   144  		//	expPass:        true,
   145  		//	expSimPass:     true,
   146  		//	expFromBalance: sdk.NewCoins(),
   147  		//	expToBalance:   coins,
   148  		//},
   149  	}
   150  
   151  	for _, test := range tests {
   152  		test := test
   153  		t.Run(test.name, func(t *testing.T) {
   154  			acc := &auth.BaseAccount{
   155  				Address: test.msg.FromAddress,
   156  				Coins:   test.fromBalance,
   157  			}
   158  
   159  			genAccs := []authexported.GenesisAccount{acc}
   160  			app := simapp.SetupWithGenesisAccounts(genAccs)
   161  
   162  			ctxCheck := app.BaseApp.NewContext(true, abci.Header{})
   163  
   164  			res1 := app.AccountKeeper.GetAccount(ctxCheck, test.msg.FromAddress)
   165  			require.NotNil(t, res1)
   166  			require.Equal(t, acc, res1.(*auth.BaseAccount))
   167  
   168  			origAccNum := res1.GetAccountNumber()
   169  			origSeq := res1.GetSequence()
   170  
   171  			header := abci.Header{Height: app.LastBlockHeight() + 1}
   172  			simapp.SignCheckDeliver(t, app.Codec(), app.BaseApp, header, []sdk.Msg{test.msg}, []uint64{origAccNum}, []uint64{origSeq}, test.expSimPass, test.expPass, priv1)
   173  
   174  			simapp.CheckBalance(t, app, test.msg.FromAddress, test.expFromBalance)
   175  			simapp.CheckBalance(t, app, test.msg.ToAddress, test.expToBalance)
   176  
   177  			res2 := app.AccountKeeper.GetAccount(app.NewContext(true, abci.Header{}), addr1)
   178  			require.NotNil(t, res2)
   179  
   180  			require.Equal(t, res2.GetAccountNumber(), origAccNum)
   181  			require.Equal(t, res2.GetSequence(), origSeq+1)
   182  		})
   183  	}
   184  }
   185  
   186  func TestMsgMultiSendWithAccounts(t *testing.T) {
   187  	acc := &auth.BaseAccount{
   188  		Address: addr1,
   189  		Coins:   sdk.Coins{sdk.NewInt64Coin("foocoin", 67)},
   190  	}
   191  
   192  	genAccs := []authexported.GenesisAccount{acc}
   193  	app := simapp.SetupWithGenesisAccounts(genAccs)
   194  
   195  	ctxCheck := app.BaseApp.NewContext(true, abci.Header{})
   196  
   197  	res1 := app.AccountKeeper.GetAccount(ctxCheck, addr1)
   198  	require.NotNil(t, res1)
   199  	require.Equal(t, acc, res1.(*auth.BaseAccount))
   200  
   201  	testCases := []appTestCase{
   202  		//{
   203  		//	msgs:       []sdk.Msg{multiSendMsg1},
   204  		//	accNums:    []uint64{0},
   205  		//	accSeqs:    []uint64{0},
   206  		//	expSimPass: true,
   207  		//	expPass:    true,
   208  		//	privKeys:   []crypto.PrivKey{priv1},
   209  		//	expectedBalances: []expectedBalance{
   210  		//		{addr1, sdk.Coins{sdk.NewInt64Coin("foocoin", 57)}},
   211  		//		{addr2, sdk.Coins{sdk.NewInt64Coin("foocoin", 10)}},
   212  		//	},
   213  		//},
   214  		//{
   215  		//	msgs:       []sdk.Msg{multiSendMsg1, multiSendMsg2},
   216  		//	accNums:    []uint64{0},
   217  		//	accSeqs:    []uint64{0},
   218  		//	expSimPass: true, // doesn't check signature
   219  		//	expPass:    false,
   220  		//	privKeys:   []crypto.PrivKey{priv1},
   221  		//},
   222  		//{
   223  		//	msgs:       []sdk.Msg{multiSendMsg5},
   224  		//	accNums:    []uint64{0},
   225  		//	accSeqs:    []uint64{0},
   226  		//	expSimPass: false,
   227  		//	expPass:    false,
   228  		//	privKeys:   []crypto.PrivKey{priv1},
   229  		//},
   230  	}
   231  
   232  	for _, tc := range testCases {
   233  		header := abci.Header{Height: app.LastBlockHeight() + 1}
   234  		simapp.SignCheckDeliver(t, app.Codec(), app.BaseApp, header, tc.msgs, tc.accNums, tc.accSeqs, tc.expSimPass, tc.expPass, tc.privKeys...)
   235  
   236  		for _, eb := range tc.expectedBalances {
   237  			simapp.CheckBalance(t, app, eb.addr, eb.coins)
   238  		}
   239  	}
   240  }
   241  
   242  func TestMsgMultiSendMultipleOut(t *testing.T) {
   243  
   244  	acc1 := &auth.BaseAccount{
   245  		Address: addr1,
   246  		Coins:   sdk.Coins{sdk.NewInt64Coin("foocoin", 42)},
   247  	}
   248  	acc2 := &auth.BaseAccount{
   249  		Address: addr2,
   250  		Coins:   sdk.Coins{sdk.NewInt64Coin("foocoin", 42)},
   251  	}
   252  
   253  	genAccs := []authexported.GenesisAccount{acc1, acc2}
   254  	app := simapp.SetupWithGenesisAccounts(genAccs)
   255  
   256  	testCases := []appTestCase{
   257  		//{
   258  		//	msgs:       []sdk.Msg{multiSendMsg2},
   259  		//	accNums:    []uint64{0},
   260  		//	accSeqs:    []uint64{0},
   261  		//	expSimPass: true,
   262  		//	expPass:    true,
   263  		//	privKeys:   []crypto.PrivKey{priv1},
   264  		//	expectedBalances: []expectedBalance{
   265  		//		{addr1, sdk.Coins{sdk.NewInt64Coin("foocoin", 32)}},
   266  		//		{addr2, sdk.Coins{sdk.NewInt64Coin("foocoin", 47)}},
   267  		//		{addr3, sdk.Coins{sdk.NewInt64Coin("foocoin", 5)}},
   268  		//	},
   269  		//},
   270  	}
   271  
   272  	for _, tc := range testCases {
   273  		header := abci.Header{Height: app.LastBlockHeight() + 1}
   274  		simapp.SignCheckDeliver(t, app.Codec(), app.BaseApp, header, tc.msgs, tc.accNums, tc.accSeqs, tc.expSimPass, tc.expPass, tc.privKeys...)
   275  
   276  		for _, eb := range tc.expectedBalances {
   277  			simapp.CheckBalance(t, app, eb.addr, eb.coins)
   278  		}
   279  	}
   280  }
   281  
   282  func TestMsgMultiSendMultipleInOut(t *testing.T) {
   283  
   284  	acc1 := &auth.BaseAccount{
   285  		Address: addr1,
   286  		Coins:   sdk.Coins{sdk.NewInt64Coin("foocoin", 42)},
   287  	}
   288  	acc2 := &auth.BaseAccount{
   289  		Address: addr2,
   290  		Coins:   sdk.Coins{sdk.NewInt64Coin("foocoin", 42)},
   291  	}
   292  	acc4 := &auth.BaseAccount{
   293  		Address: addr4,
   294  		Coins:   sdk.Coins{sdk.NewInt64Coin("foocoin", 42)},
   295  	}
   296  
   297  	genAccs := []authexported.GenesisAccount{acc1, acc2, acc4}
   298  	app := simapp.SetupWithGenesisAccounts(genAccs)
   299  
   300  	testCases := []appTestCase{
   301  		//{
   302  		//	msgs:       []sdk.Msg{multiSendMsg3},
   303  		//	accNums:    []uint64{0, 2},
   304  		//	accSeqs:    []uint64{0, 0},
   305  		//	expSimPass: true,
   306  		//	expPass:    true,
   307  		//	privKeys:   []crypto.PrivKey{priv1, priv4},
   308  		//	expectedBalances: []expectedBalance{
   309  		//		{addr1, sdk.Coins{sdk.NewInt64Coin("foocoin", 32)}},
   310  		//		{addr4, sdk.Coins{sdk.NewInt64Coin("foocoin", 32)}},
   311  		//		{addr2, sdk.Coins{sdk.NewInt64Coin("foocoin", 52)}},
   312  		//		{addr3, sdk.Coins{sdk.NewInt64Coin("foocoin", 10)}},
   313  		//	},
   314  		//},
   315  	}
   316  
   317  	for _, tc := range testCases {
   318  		header := abci.Header{Height: app.LastBlockHeight() + 1}
   319  		simapp.SignCheckDeliver(t, app.Codec(), app.BaseApp, header, tc.msgs, tc.accNums, tc.accSeqs, tc.expSimPass, tc.expPass, tc.privKeys...)
   320  
   321  		for _, eb := range tc.expectedBalances {
   322  			simapp.CheckBalance(t, app, eb.addr, eb.coins)
   323  		}
   324  	}
   325  }
   326  
   327  func TestMsgMultiSendDependent(t *testing.T) {
   328  	acc1 := auth.NewBaseAccountWithAddress(addr1)
   329  	acc2 := auth.NewBaseAccountWithAddress(addr2)
   330  	err := acc1.SetCoins(sdk.NewCoins(sdk.NewInt64Coin("foocoin", 42)))
   331  	require.NoError(t, err)
   332  	err = acc2.SetAccountNumber(1)
   333  	require.NoError(t, err)
   334  
   335  	genAccs := []authexported.GenesisAccount{&acc1, &acc2}
   336  	app := simapp.SetupWithGenesisAccounts(genAccs)
   337  
   338  	testCases := []appTestCase{
   339  		//{
   340  		//	msgs:       []sdk.Msg{multiSendMsg1},
   341  		//	accNums:    []uint64{0},
   342  		//	accSeqs:    []uint64{0},
   343  		//	expSimPass: true,
   344  		//	expPass:    true,
   345  		//	privKeys:   []crypto.PrivKey{priv1},
   346  		//	expectedBalances: []expectedBalance{
   347  		//		{addr1, sdk.Coins{sdk.NewInt64Coin("foocoin", 32)}},
   348  		//		{addr2, sdk.Coins{sdk.NewInt64Coin("foocoin", 10)}},
   349  		//	},
   350  		//},
   351  		//{
   352  		//	msgs:       []sdk.Msg{multiSendMsg4},
   353  		//	accNums:    []uint64{1},
   354  		//	accSeqs:    []uint64{0},
   355  		//	expSimPass: true,
   356  		//	expPass:    true,
   357  		//	privKeys:   []crypto.PrivKey{priv2},
   358  		//	expectedBalances: []expectedBalance{
   359  		//		{addr1, sdk.Coins{sdk.NewInt64Coin("foocoin", 42)}},
   360  		//	},
   361  		//},
   362  	}
   363  
   364  	for _, tc := range testCases {
   365  		header := abci.Header{Height: app.LastBlockHeight() + 1}
   366  		simapp.SignCheckDeliver(t, app.Codec(), app.BaseApp, header, tc.msgs, tc.accNums, tc.accSeqs, tc.expSimPass, tc.expPass, tc.privKeys...)
   367  
   368  		for _, eb := range tc.expectedBalances {
   369  			simapp.CheckBalance(t, app, eb.addr, eb.coins)
   370  		}
   371  	}
   372  }