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 }