github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/cosmos-sdk/x/bank/internal/keeper/keeper_test.go (about) 1 package keeper_test 2 3 import ( 4 "testing" 5 "time" 6 7 abci "github.com/fibonacci-chain/fbc/libs/tendermint/abci/types" 8 tmkv "github.com/fibonacci-chain/fbc/libs/tendermint/libs/kv" 9 tmtime "github.com/fibonacci-chain/fbc/libs/tendermint/types/time" 10 "github.com/stretchr/testify/require" 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 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/auth/vesting" 16 keep "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/bank/internal/keeper" 17 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/bank/internal/types" 18 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/supply" 19 ) 20 21 const ( 22 fooDenom = "foo" 23 barDenom = "bar" 24 ) 25 26 func TestKeeper(t *testing.T) { 27 app, ctx := createTestApp(false) 28 29 addr := sdk.AccAddress([]byte("addr1")) 30 addr2 := sdk.AccAddress([]byte("addr2")) 31 addr3 := sdk.AccAddress([]byte("addr3")) 32 acc := app.AccountKeeper.NewAccountWithAddress(ctx, addr) 33 34 // Test GetCoins/SetCoins 35 app.AccountKeeper.SetAccount(ctx, acc) 36 require.True(t, app.BankKeeper.GetCoins(ctx, addr).IsEqual(sdk.NewCoins())) 37 38 app.BankKeeper.SetCoins(ctx, addr, sdk.NewCoins(sdk.NewInt64Coin("foocoin", 10))) 39 require.True(t, app.BankKeeper.GetCoins(ctx, addr).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("foocoin", 10)))) 40 41 // Test HasCoins 42 require.True(t, app.BankKeeper.HasCoins(ctx, addr, sdk.NewCoins(sdk.NewInt64Coin("foocoin", 10)))) 43 require.True(t, app.BankKeeper.HasCoins(ctx, addr, sdk.NewCoins(sdk.NewInt64Coin("foocoin", 5)))) 44 require.False(t, app.BankKeeper.HasCoins(ctx, addr, sdk.NewCoins(sdk.NewInt64Coin("foocoin", 15)))) 45 require.False(t, app.BankKeeper.HasCoins(ctx, addr, sdk.NewCoins(sdk.NewInt64Coin("barcoin", 5)))) 46 47 // Test AddCoins 48 app.BankKeeper.AddCoins(ctx, addr, sdk.NewCoins(sdk.NewInt64Coin("foocoin", 15))) 49 require.True(t, app.BankKeeper.GetCoins(ctx, addr).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("foocoin", 25)))) 50 51 app.BankKeeper.AddCoins(ctx, addr, sdk.NewCoins(sdk.NewInt64Coin("barcoin", 15))) 52 require.True(t, app.BankKeeper.GetCoins(ctx, addr).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("barcoin", 15), sdk.NewInt64Coin("foocoin", 25)))) 53 54 // Test SubtractCoins 55 app.BankKeeper.SubtractCoins(ctx, addr, sdk.NewCoins(sdk.NewInt64Coin("foocoin", 10))) 56 app.BankKeeper.SubtractCoins(ctx, addr, sdk.NewCoins(sdk.NewInt64Coin("barcoin", 5))) 57 require.True(t, app.BankKeeper.GetCoins(ctx, addr).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("barcoin", 10), sdk.NewInt64Coin("foocoin", 15)))) 58 59 app.BankKeeper.SubtractCoins(ctx, addr, sdk.NewCoins(sdk.NewInt64Coin("barcoin", 11))) 60 require.True(t, app.BankKeeper.GetCoins(ctx, addr).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("barcoin", 10), sdk.NewInt64Coin("foocoin", 15)))) 61 62 app.BankKeeper.SubtractCoins(ctx, addr, sdk.NewCoins(sdk.NewInt64Coin("barcoin", 10))) 63 require.True(t, app.BankKeeper.GetCoins(ctx, addr).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("foocoin", 15)))) 64 require.False(t, app.BankKeeper.HasCoins(ctx, addr, sdk.NewCoins(sdk.NewInt64Coin("barcoin", 1)))) 65 66 // Test SendCoins 67 app.BankKeeper.SendCoins(ctx, addr, addr2, sdk.NewCoins(sdk.NewInt64Coin("foocoin", 5))) 68 require.True(t, app.BankKeeper.GetCoins(ctx, addr).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("foocoin", 10)))) 69 require.True(t, app.BankKeeper.GetCoins(ctx, addr2).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("foocoin", 5)))) 70 71 app.BankKeeper.SendCoins(ctx, addr, addr2, sdk.NewCoins(sdk.NewInt64Coin("foocoin", 50))) 72 require.True(t, app.BankKeeper.GetCoins(ctx, addr).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("foocoin", 10)))) 73 require.True(t, app.BankKeeper.GetCoins(ctx, addr2).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("foocoin", 5)))) 74 75 app.BankKeeper.AddCoins(ctx, addr, sdk.NewCoins(sdk.NewInt64Coin("barcoin", 30))) 76 app.BankKeeper.SendCoins(ctx, addr, addr2, sdk.NewCoins(sdk.NewInt64Coin("barcoin", 10), sdk.NewInt64Coin("foocoin", 5))) 77 require.True(t, app.BankKeeper.GetCoins(ctx, addr).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("barcoin", 20), sdk.NewInt64Coin("foocoin", 5)))) 78 require.True(t, app.BankKeeper.GetCoins(ctx, addr2).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("barcoin", 10), sdk.NewInt64Coin("foocoin", 10)))) 79 80 // Test InputOutputCoins 81 input1 := types.NewInput(addr2, sdk.NewCoins(sdk.NewInt64Coin("foocoin", 2))) 82 output1 := types.NewOutput(addr, sdk.NewCoins(sdk.NewInt64Coin("foocoin", 2))) 83 app.BankKeeper.InputOutputCoins(ctx, []types.Input{input1}, []types.Output{output1}) 84 require.True(t, app.BankKeeper.GetCoins(ctx, addr).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("barcoin", 20), sdk.NewInt64Coin("foocoin", 7)))) 85 require.True(t, app.BankKeeper.GetCoins(ctx, addr2).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("barcoin", 10), sdk.NewInt64Coin("foocoin", 8)))) 86 87 inputs := []types.Input{ 88 types.NewInput(addr, sdk.NewCoins(sdk.NewInt64Coin("foocoin", 3))), 89 types.NewInput(addr2, sdk.NewCoins(sdk.NewInt64Coin("barcoin", 3), sdk.NewInt64Coin("foocoin", 2))), 90 } 91 92 outputs := []types.Output{ 93 types.NewOutput(addr, sdk.NewCoins(sdk.NewInt64Coin("barcoin", 1))), 94 types.NewOutput(addr3, sdk.NewCoins(sdk.NewInt64Coin("barcoin", 2), sdk.NewInt64Coin("foocoin", 5))), 95 } 96 app.BankKeeper.InputOutputCoins(ctx, inputs, outputs) 97 require.True(t, app.BankKeeper.GetCoins(ctx, addr).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("barcoin", 21), sdk.NewInt64Coin("foocoin", 4)))) 98 require.True(t, app.BankKeeper.GetCoins(ctx, addr2).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("barcoin", 7), sdk.NewInt64Coin("foocoin", 6)))) 99 require.True(t, app.BankKeeper.GetCoins(ctx, addr3).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("barcoin", 2), sdk.NewInt64Coin("foocoin", 5)))) 100 101 // Test retrieving black listed accounts 102 for acc := range simapp.GetMaccPerms() { 103 addr := supply.NewModuleAddress(acc) 104 require.Equal(t, app.BlacklistedAccAddrs()[addr.String()], app.BankKeeper.BlacklistedAddr(addr)) 105 } 106 } 107 108 func TestSendKeeper(t *testing.T) { 109 app, ctx := createTestApp(false) 110 111 blacklistedAddrs := make(map[string]bool) 112 113 paramSpace := app.ParamsKeeper.Subspace("newspace") 114 sendKeeper := keep.NewBaseSendKeeper(app.AccountKeeper, paramSpace, blacklistedAddrs) 115 app.BankKeeper.SetSendEnabled(ctx, true) 116 117 addr := sdk.AccAddress([]byte("addr1")) 118 addr2 := sdk.AccAddress([]byte("addr2")) 119 acc := app.AccountKeeper.NewAccountWithAddress(ctx, addr) 120 121 // Test GetCoins/SetCoins 122 app.AccountKeeper.SetAccount(ctx, acc) 123 require.True(t, sendKeeper.GetCoins(ctx, addr).IsEqual(sdk.NewCoins())) 124 125 app.BankKeeper.SetCoins(ctx, addr, sdk.NewCoins(sdk.NewInt64Coin("foocoin", 10))) 126 require.True(t, sendKeeper.GetCoins(ctx, addr).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("foocoin", 10)))) 127 128 // Test HasCoins 129 require.True(t, sendKeeper.HasCoins(ctx, addr, sdk.NewCoins(sdk.NewInt64Coin("foocoin", 10)))) 130 require.True(t, sendKeeper.HasCoins(ctx, addr, sdk.NewCoins(sdk.NewInt64Coin("foocoin", 5)))) 131 require.False(t, sendKeeper.HasCoins(ctx, addr, sdk.NewCoins(sdk.NewInt64Coin("foocoin", 15)))) 132 require.False(t, sendKeeper.HasCoins(ctx, addr, sdk.NewCoins(sdk.NewInt64Coin("barcoin", 5)))) 133 134 app.BankKeeper.SetCoins(ctx, addr, sdk.NewCoins(sdk.NewInt64Coin("foocoin", 15))) 135 136 // Test SendCoins 137 sendKeeper.SendCoins(ctx, addr, addr2, sdk.NewCoins(sdk.NewInt64Coin("foocoin", 5))) 138 require.True(t, sendKeeper.GetCoins(ctx, addr).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("foocoin", 10)))) 139 require.True(t, sendKeeper.GetCoins(ctx, addr2).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("foocoin", 5)))) 140 141 sendKeeper.SendCoins(ctx, addr, addr2, sdk.NewCoins(sdk.NewInt64Coin("foocoin", 50))) 142 require.True(t, sendKeeper.GetCoins(ctx, addr).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("foocoin", 10)))) 143 require.True(t, sendKeeper.GetCoins(ctx, addr2).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("foocoin", 5)))) 144 145 app.BankKeeper.AddCoins(ctx, addr, sdk.NewCoins(sdk.NewInt64Coin("barcoin", 30))) 146 sendKeeper.SendCoins(ctx, addr, addr2, sdk.NewCoins(sdk.NewInt64Coin("barcoin", 10), sdk.NewInt64Coin("foocoin", 5))) 147 require.True(t, sendKeeper.GetCoins(ctx, addr).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("barcoin", 20), sdk.NewInt64Coin("foocoin", 5)))) 148 require.True(t, sendKeeper.GetCoins(ctx, addr2).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("barcoin", 10), sdk.NewInt64Coin("foocoin", 10)))) 149 150 // validate coins with invalid denoms or negative values cannot be sent 151 // NOTE: We must use the Coin literal as the constructor does not allow 152 // negative values. 153 err := sendKeeper.SendCoins(ctx, addr, addr2, sdk.Coins{sdk.Coin{Denom: "FOOCOIN", Amount: sdk.NewDec(-5)}}) 154 require.Error(t, err) 155 } 156 157 func TestInputOutputNewAccount(t *testing.T) { 158 app, ctx := createTestApp(false) 159 balances := sdk.NewCoins(sdk.NewInt64Coin("foo", 100), sdk.NewInt64Coin("bar", 50)) 160 addr1 := sdk.AccAddress([]byte("addr1")) 161 acc1 := app.AccountKeeper.NewAccountWithAddress(ctx, addr1) 162 163 app.AccountKeeper.SetAccount(ctx, acc1) 164 require.NoError(t, app.BankKeeper.SetCoins(ctx, addr1, balances)) 165 166 acc1Balances := app.BankKeeper.GetCoins(ctx, addr1) 167 require.Equal(t, balances, acc1Balances) 168 169 addr2 := sdk.AccAddress([]byte("addr2")) 170 171 require.Nil(t, app.AccountKeeper.GetAccount(ctx, addr2)) 172 require.Empty(t, app.BankKeeper.GetCoins(ctx, addr2)) 173 174 inputs := []types.Input{ 175 {Address: addr1, Coins: sdk.NewCoins(sdk.NewInt64Coin("foo", 30), sdk.NewInt64Coin("bar", 10))}, 176 } 177 outputs := []types.Output{ 178 {Address: addr2, Coins: sdk.NewCoins(sdk.NewInt64Coin("foo", 30), sdk.NewInt64Coin("bar", 10))}, 179 } 180 181 require.NoError(t, app.BankKeeper.InputOutputCoins(ctx, inputs, outputs)) 182 183 expected := sdk.NewCoins(sdk.NewInt64Coin("foo", 30), sdk.NewInt64Coin("bar", 10)) 184 acc2Balances := app.BankKeeper.GetCoins(ctx, addr2) 185 require.Equal(t, expected, acc2Balances) 186 require.NotNil(t, app.AccountKeeper.GetAccount(ctx, addr2)) 187 } 188 189 func TestMsgSendEvents(t *testing.T) { 190 app, ctx := createTestApp(false) 191 192 app.BankKeeper.SetSendEnabled(ctx, true) 193 194 addr := sdk.AccAddress([]byte("addr1")) 195 addr2 := sdk.AccAddress([]byte("addr2")) 196 acc := app.AccountKeeper.NewAccountWithAddress(ctx, addr) 197 198 app.AccountKeeper.SetAccount(ctx, acc) 199 newCoins := sdk.NewCoins(sdk.NewInt64Coin("foocoin", 50)) 200 err := app.BankKeeper.SendCoins(ctx, addr, addr2, newCoins) 201 require.Error(t, err) 202 events := ctx.EventManager().Events() 203 require.Equal(t, 2, len(events)) 204 event1 := sdk.Event{ 205 Type: types.EventTypeTransfer, 206 Attributes: []tmkv.Pair{}, 207 } 208 event1.Attributes = append( 209 event1.Attributes, 210 tmkv.Pair{Key: []byte(types.AttributeKeyRecipient), Value: []byte(addr2.String())}, 211 tmkv.Pair{Key: []byte(types.AttributeKeySender), Value: []byte(addr.String())}, 212 tmkv.Pair{Key: []byte(sdk.AttributeKeyAmount), Value: []byte(newCoins.String())}) 213 event2 := sdk.Event{ 214 Type: sdk.EventTypeMessage, 215 Attributes: []tmkv.Pair{}, 216 } 217 event2.Attributes = append( 218 event2.Attributes, 219 tmkv.Pair{Key: []byte(types.AttributeKeySender), Value: []byte(addr.String())}) 220 require.Equal(t, event1, events[0]) 221 require.Equal(t, event2, events[1]) 222 223 app.BankKeeper.SetCoins(ctx, addr, sdk.NewCoins(sdk.NewInt64Coin("foocoin", 50))) 224 newCoins = sdk.NewCoins(sdk.NewInt64Coin("foocoin", 50)) 225 err = app.BankKeeper.SendCoins(ctx, addr, addr2, newCoins) 226 require.NoError(t, err) 227 events = ctx.EventManager().Events() 228 require.Equal(t, 4, len(events)) 229 require.Equal(t, event1, events[2]) 230 require.Equal(t, event2, events[3]) 231 } 232 233 func TestMsgMultiSendEvents(t *testing.T) { 234 app, ctx := createTestApp(false) 235 236 app.BankKeeper.SetSendEnabled(ctx, true) 237 238 addr := sdk.AccAddress([]byte("addr1")) 239 addr2 := sdk.AccAddress([]byte("addr2")) 240 addr3 := sdk.AccAddress([]byte("addr3")) 241 addr4 := sdk.AccAddress([]byte("addr4")) 242 acc := app.AccountKeeper.NewAccountWithAddress(ctx, addr) 243 acc2 := app.AccountKeeper.NewAccountWithAddress(ctx, addr2) 244 245 app.AccountKeeper.SetAccount(ctx, acc) 246 app.AccountKeeper.SetAccount(ctx, acc2) 247 newCoins := sdk.NewCoins(sdk.NewInt64Coin("foocoin", 50)) 248 newCoins2 := sdk.NewCoins(sdk.NewInt64Coin("barcoin", 100)) 249 inputs := []types.Input{ 250 {Address: addr, Coins: newCoins}, 251 {Address: addr2, Coins: newCoins2}, 252 } 253 outputs := []types.Output{ 254 {Address: addr3, Coins: newCoins}, 255 {Address: addr4, Coins: newCoins2}, 256 } 257 err := app.BankKeeper.InputOutputCoins(ctx, inputs, outputs) 258 require.Error(t, err) 259 events := ctx.EventManager().Events() 260 require.Equal(t, 0, len(events)) 261 262 // Set addr's coins but not addr2's coins 263 app.BankKeeper.SetCoins(ctx, addr, sdk.NewCoins(sdk.NewInt64Coin("foocoin", 50))) 264 265 err = app.BankKeeper.InputOutputCoins(ctx, inputs, outputs) 266 require.Error(t, err) 267 events = ctx.EventManager().Events() 268 require.Equal(t, 1, len(events)) 269 event1 := sdk.Event{ 270 Type: sdk.EventTypeMessage, 271 Attributes: []tmkv.Pair{}, 272 } 273 event1.Attributes = append( 274 event1.Attributes, 275 tmkv.Pair{Key: []byte(types.AttributeKeySender), Value: []byte(addr.String())}) 276 require.Equal(t, event1, events[0]) 277 278 // Set addr's coins and addr2's coins 279 app.BankKeeper.SetCoins(ctx, addr, sdk.NewCoins(sdk.NewInt64Coin("foocoin", 50))) 280 newCoins = sdk.NewCoins(sdk.NewInt64Coin("foocoin", 50)) 281 app.BankKeeper.SetCoins(ctx, addr2, sdk.NewCoins(sdk.NewInt64Coin("barcoin", 100))) 282 newCoins2 = sdk.NewCoins(sdk.NewInt64Coin("barcoin", 100)) 283 284 err = app.BankKeeper.InputOutputCoins(ctx, inputs, outputs) 285 require.NoError(t, err) 286 events = ctx.EventManager().Events() 287 require.Equal(t, 5, len(events)) 288 event2 := sdk.Event{ 289 Type: sdk.EventTypeMessage, 290 Attributes: []tmkv.Pair{}, 291 } 292 event2.Attributes = append( 293 event2.Attributes, 294 tmkv.Pair{Key: []byte(types.AttributeKeySender), Value: []byte(addr2.String())}) 295 event3 := sdk.Event{ 296 Type: types.EventTypeTransfer, 297 Attributes: []tmkv.Pair{}, 298 } 299 event3.Attributes = append( 300 event3.Attributes, 301 tmkv.Pair{Key: []byte(types.AttributeKeyRecipient), Value: []byte(addr3.String())}) 302 event3.Attributes = append( 303 event3.Attributes, 304 tmkv.Pair{Key: []byte(sdk.AttributeKeyAmount), Value: []byte(newCoins.String())}) 305 event4 := sdk.Event{ 306 Type: types.EventTypeTransfer, 307 Attributes: []tmkv.Pair{}, 308 } 309 event4.Attributes = append( 310 event4.Attributes, 311 tmkv.Pair{Key: []byte(types.AttributeKeyRecipient), Value: []byte(addr4.String())}) 312 event4.Attributes = append( 313 event4.Attributes, 314 tmkv.Pair{Key: []byte(sdk.AttributeKeyAmount), Value: []byte(newCoins2.String())}) 315 require.Equal(t, event1, events[1]) 316 require.Equal(t, event2, events[2]) 317 require.Equal(t, event3, events[3]) 318 require.Equal(t, event4, events[4]) 319 } 320 321 func TestViewKeeper(t *testing.T) { 322 app, ctx := createTestApp(false) 323 324 //paramSpace := app.ParamsKeeper.Subspace(types.DefaultParamspace) 325 viewKeeper := keep.NewBaseViewKeeper(app.AccountKeeper) 326 327 addr := sdk.AccAddress([]byte("addr1")) 328 acc := app.AccountKeeper.NewAccountWithAddress(ctx, addr) 329 330 // Test GetCoins/SetCoins 331 app.AccountKeeper.SetAccount(ctx, acc) 332 require.True(t, viewKeeper.GetCoins(ctx, addr).IsEqual(sdk.NewCoins())) 333 334 app.BankKeeper.SetCoins(ctx, addr, sdk.NewCoins(sdk.NewInt64Coin("foocoin", 10))) 335 require.True(t, viewKeeper.GetCoins(ctx, addr).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("foocoin", 10)))) 336 337 // Test HasCoins 338 require.True(t, viewKeeper.HasCoins(ctx, addr, sdk.NewCoins(sdk.NewInt64Coin("foocoin", 10)))) 339 require.True(t, viewKeeper.HasCoins(ctx, addr, sdk.NewCoins(sdk.NewInt64Coin("foocoin", 5)))) 340 require.False(t, viewKeeper.HasCoins(ctx, addr, sdk.NewCoins(sdk.NewInt64Coin("foocoin", 15)))) 341 require.False(t, viewKeeper.HasCoins(ctx, addr, sdk.NewCoins(sdk.NewInt64Coin("barcoin", 5)))) 342 } 343 344 func TestVestingAccountSend(t *testing.T) { 345 app, ctx := createTestApp(false) 346 now := tmtime.Now() 347 ctx.SetBlockHeader(abci.Header{Time: now}) 348 endTime := now.Add(24 * time.Hour) 349 350 origCoins := sdk.NewCoins(sdk.NewInt64Coin("stake", 100)) 351 sendCoins := sdk.NewCoins(sdk.NewInt64Coin("stake", 50)) 352 353 addr1 := sdk.AccAddress([]byte("addr1")) 354 addr2 := sdk.AccAddress([]byte("addr2")) 355 bacc := auth.NewBaseAccountWithAddress(addr1) 356 bacc.SetCoins(origCoins) 357 vacc := vesting.NewContinuousVestingAccount(&bacc, ctx.BlockHeader().Time.Unix(), endTime.Unix()) 358 app.AccountKeeper.SetAccount(ctx, vacc) 359 360 // require that no coins be sendable at the beginning of the vesting schedule 361 err := app.BankKeeper.SendCoins(ctx, addr1, addr2, sendCoins) 362 require.Error(t, err) 363 364 // receive some coins 365 vacc.SetCoins(origCoins.Add(sendCoins...)) 366 app.AccountKeeper.SetAccount(ctx, vacc) 367 368 // require that all vested coins are spendable plus any received 369 ctx.SetBlockTime(now.Add(12 * time.Hour)) 370 err = app.BankKeeper.SendCoins(ctx, addr1, addr2, sendCoins) 371 vacc = app.AccountKeeper.GetAccount(ctx, addr1).(*vesting.ContinuousVestingAccount) 372 require.NoError(t, err) 373 require.Equal(t, origCoins, vacc.GetCoins()) 374 } 375 376 func TestPeriodicVestingAccountSend(t *testing.T) { 377 app, ctx := createTestApp(false) 378 now := tmtime.Now() 379 ctx.SetBlockHeader(abci.Header{Time: now}) 380 origCoins := sdk.NewCoins(sdk.NewInt64Coin("stake", 100)) 381 sendCoins := sdk.NewCoins(sdk.NewInt64Coin("stake", 50)) 382 383 addr1 := sdk.AccAddress([]byte("addr1")) 384 addr2 := sdk.AccAddress([]byte("addr2")) 385 bacc := auth.NewBaseAccountWithAddress(addr1) 386 bacc.SetCoins(origCoins) 387 periods := vesting.Periods{ 388 vesting.Period{Length: int64(12 * 60 * 60), Amount: sdk.Coins{sdk.NewInt64Coin("stake", 50)}}, 389 vesting.Period{Length: int64(6 * 60 * 60), Amount: sdk.Coins{sdk.NewInt64Coin("stake", 25)}}, 390 vesting.Period{Length: int64(6 * 60 * 60), Amount: sdk.Coins{sdk.NewInt64Coin("stake", 25)}}, 391 } 392 vacc := vesting.NewPeriodicVestingAccount(&bacc, ctx.BlockHeader().Time.Unix(), periods) 393 app.AccountKeeper.SetAccount(ctx, vacc) 394 395 // require that no coins be sendable at the beginning of the vesting schedule 396 err := app.BankKeeper.SendCoins(ctx, addr1, addr2, sendCoins) 397 require.Error(t, err) 398 399 // receive some coins 400 vacc.SetCoins(origCoins.Add(sendCoins...)) 401 app.AccountKeeper.SetAccount(ctx, vacc) 402 403 // require that all vested coins are spendable plus any received 404 ctx.SetBlockTime(now.Add(12 * time.Hour)) 405 err = app.BankKeeper.SendCoins(ctx, addr1, addr2, sendCoins) 406 vacc = app.AccountKeeper.GetAccount(ctx, addr1).(*vesting.PeriodicVestingAccount) 407 require.NoError(t, err) 408 require.Equal(t, origCoins, vacc.GetCoins()) 409 } 410 411 func TestVestingAccountReceive(t *testing.T) { 412 app, ctx := createTestApp(false) 413 now := tmtime.Now() 414 ctx.SetBlockHeader(abci.Header{Time: now}) 415 endTime := now.Add(24 * time.Hour) 416 417 origCoins := sdk.NewCoins(sdk.NewInt64Coin("stake", 100)) 418 sendCoins := sdk.NewCoins(sdk.NewInt64Coin("stake", 50)) 419 420 addr1 := sdk.AccAddress([]byte("addr1")) 421 addr2 := sdk.AccAddress([]byte("addr2")) 422 423 bacc := auth.NewBaseAccountWithAddress(addr1) 424 bacc.SetCoins(origCoins) 425 vacc := vesting.NewContinuousVestingAccount(&bacc, ctx.BlockHeader().Time.Unix(), endTime.Unix()) 426 acc := app.AccountKeeper.NewAccountWithAddress(ctx, addr2) 427 app.AccountKeeper.SetAccount(ctx, vacc) 428 app.AccountKeeper.SetAccount(ctx, acc) 429 app.BankKeeper.SetCoins(ctx, addr2, origCoins) 430 431 // send some coins to the vesting account 432 app.BankKeeper.SendCoins(ctx, addr2, addr1, sendCoins) 433 434 // require the coins are spendable 435 vacc = app.AccountKeeper.GetAccount(ctx, addr1).(*vesting.ContinuousVestingAccount) 436 require.Equal(t, origCoins.Add(sendCoins...), vacc.GetCoins()) 437 require.Equal(t, vacc.SpendableCoins(now), sendCoins) 438 439 // require coins are spendable plus any that have vested 440 require.Equal(t, vacc.SpendableCoins(now.Add(12*time.Hour)), origCoins) 441 } 442 443 func TestPeriodicVestingAccountReceive(t *testing.T) { 444 app, ctx := createTestApp(false) 445 now := tmtime.Now() 446 ctx.SetBlockHeader(abci.Header{Time: now}) 447 448 origCoins := sdk.NewCoins(sdk.NewInt64Coin("stake", 100)) 449 sendCoins := sdk.NewCoins(sdk.NewInt64Coin("stake", 50)) 450 451 addr1 := sdk.AccAddress([]byte("addr1")) 452 addr2 := sdk.AccAddress([]byte("addr2")) 453 454 bacc := auth.NewBaseAccountWithAddress(addr1) 455 bacc.SetCoins(origCoins) 456 periods := vesting.Periods{ 457 vesting.Period{Length: int64(12 * 60 * 60), Amount: sdk.Coins{sdk.NewInt64Coin("stake", 50)}}, 458 vesting.Period{Length: int64(6 * 60 * 60), Amount: sdk.Coins{sdk.NewInt64Coin("stake", 25)}}, 459 vesting.Period{Length: int64(6 * 60 * 60), Amount: sdk.Coins{sdk.NewInt64Coin("stake", 25)}}, 460 } 461 vacc := vesting.NewPeriodicVestingAccount(&bacc, ctx.BlockHeader().Time.Unix(), periods) 462 acc := app.AccountKeeper.NewAccountWithAddress(ctx, addr2) 463 app.AccountKeeper.SetAccount(ctx, vacc) 464 app.AccountKeeper.SetAccount(ctx, acc) 465 app.BankKeeper.SetCoins(ctx, addr2, origCoins) 466 467 // send some coins to the vesting account 468 app.BankKeeper.SendCoins(ctx, addr2, addr1, sendCoins) 469 470 // require the coins are spendable 471 vacc = app.AccountKeeper.GetAccount(ctx, addr1).(*vesting.PeriodicVestingAccount) 472 require.Equal(t, origCoins.Add(sendCoins...), vacc.GetCoins()) 473 require.Equal(t, vacc.SpendableCoins(now), sendCoins) 474 475 // require coins are spendable plus any that have vested 476 require.Equal(t, vacc.SpendableCoins(now.Add(12*time.Hour)), origCoins) 477 } 478 479 func TestDelegateCoins(t *testing.T) { 480 app, ctx := createTestApp(false) 481 now := tmtime.Now() 482 ctx.SetBlockHeader(abci.Header{Time: now}) 483 endTime := now.Add(24 * time.Hour) 484 ak := app.AccountKeeper 485 486 origCoins := sdk.NewCoins(sdk.NewInt64Coin("stake", 100)) 487 delCoins := sdk.NewCoins(sdk.NewInt64Coin("stake", 50)) 488 489 addr1 := sdk.AccAddress([]byte("addr1")) 490 addr2 := sdk.AccAddress([]byte("addr2")) 491 addrModule := sdk.AccAddress([]byte("moduleAcc")) 492 493 bacc := auth.NewBaseAccountWithAddress(addr1) 494 bacc.SetCoins(origCoins) 495 macc := ak.NewAccountWithAddress(ctx, addrModule) // we don't need to define an actual module account bc we just need the address for testing 496 vacc := vesting.NewContinuousVestingAccount(&bacc, ctx.BlockHeader().Time.Unix(), endTime.Unix()) 497 acc := ak.NewAccountWithAddress(ctx, addr2) 498 ak.SetAccount(ctx, vacc) 499 ak.SetAccount(ctx, acc) 500 ak.SetAccount(ctx, macc) 501 app.BankKeeper.SetCoins(ctx, addr2, origCoins) 502 503 ctx.SetBlockTime(now.Add(12 * time.Hour)) 504 505 // require the ability for a non-vesting account to delegate 506 err := app.BankKeeper.DelegateCoins(ctx, addr2, addrModule, delCoins) 507 acc = ak.GetAccount(ctx, addr2) 508 macc = ak.GetAccount(ctx, addrModule) 509 require.NoError(t, err) 510 require.Equal(t, origCoins.Sub(delCoins), acc.GetCoins()) 511 require.Equal(t, delCoins, macc.GetCoins()) 512 513 // require the ability for a vesting account to delegate 514 err = app.BankKeeper.DelegateCoins(ctx, addr1, addrModule, delCoins) 515 vacc = ak.GetAccount(ctx, addr1).(*vesting.ContinuousVestingAccount) 516 require.NoError(t, err) 517 require.Equal(t, delCoins, vacc.GetCoins()) 518 } 519 520 func TestUndelegateCoins(t *testing.T) { 521 app, ctx := createTestApp(false) 522 now := tmtime.Now() 523 ctx.SetBlockHeader(abci.Header{Time: now}) 524 endTime := now.Add(24 * time.Hour) 525 ak := app.AccountKeeper 526 527 origCoins := sdk.NewCoins(sdk.NewInt64Coin("stake", 100)) 528 delCoins := sdk.NewCoins(sdk.NewInt64Coin("stake", 50)) 529 530 addr1 := sdk.AccAddress([]byte("addr1")) 531 addr2 := sdk.AccAddress([]byte("addr2")) 532 addrModule := sdk.AccAddress([]byte("moduleAcc")) 533 534 bacc := auth.NewBaseAccountWithAddress(addr1) 535 bacc.SetCoins(origCoins) 536 macc := ak.NewAccountWithAddress(ctx, addrModule) // we don't need to define an actual module account bc we just need the address for testing 537 vacc := vesting.NewContinuousVestingAccount(&bacc, ctx.BlockHeader().Time.Unix(), endTime.Unix()) 538 acc := ak.NewAccountWithAddress(ctx, addr2) 539 ak.SetAccount(ctx, vacc) 540 ak.SetAccount(ctx, acc) 541 ak.SetAccount(ctx, macc) 542 app.BankKeeper.SetCoins(ctx, addr2, origCoins) 543 544 ctx.SetBlockTime(now.Add(12 * time.Hour)) 545 546 // require the ability for a non-vesting account to delegate 547 err := app.BankKeeper.DelegateCoins(ctx, addr2, addrModule, delCoins) 548 require.NoError(t, err) 549 550 acc = ak.GetAccount(ctx, addr2) 551 macc = ak.GetAccount(ctx, addrModule) 552 require.Equal(t, origCoins.Sub(delCoins), acc.GetCoins()) 553 require.Equal(t, delCoins, macc.GetCoins()) 554 555 // require the ability for a non-vesting account to undelegate 556 err = app.BankKeeper.UndelegateCoins(ctx, addrModule, addr2, delCoins) 557 require.NoError(t, err) 558 559 acc = ak.GetAccount(ctx, addr2) 560 macc = ak.GetAccount(ctx, addrModule) 561 require.Equal(t, origCoins, acc.GetCoins()) 562 require.True(t, macc.GetCoins().Empty()) 563 564 // require the ability for a vesting account to delegate 565 err = app.BankKeeper.DelegateCoins(ctx, addr1, addrModule, delCoins) 566 require.NoError(t, err) 567 568 vacc = ak.GetAccount(ctx, addr1).(*vesting.ContinuousVestingAccount) 569 macc = ak.GetAccount(ctx, addrModule) 570 require.Equal(t, origCoins.Sub(delCoins), vacc.GetCoins()) 571 require.Equal(t, delCoins, macc.GetCoins()) 572 573 // require the ability for a vesting account to undelegate 574 err = app.BankKeeper.UndelegateCoins(ctx, addrModule, addr1, delCoins) 575 require.NoError(t, err) 576 577 vacc = ak.GetAccount(ctx, addr1).(*vesting.ContinuousVestingAccount) 578 macc = ak.GetAccount(ctx, addrModule) 579 require.Equal(t, origCoins, vacc.GetCoins()) 580 require.True(t, macc.GetCoins().Empty()) 581 } 582 583 func newFooCoin(amt int64) sdk.Coin { 584 return sdk.NewInt64Coin(fooDenom, amt) 585 } 586 587 func newBarCoin(amt int64) sdk.Coin { 588 return sdk.NewInt64Coin(barDenom, amt) 589 } 590 591 func TestUndelegateCoins_Invalid(t *testing.T) { 592 app, ctx := createTestApp(false) 593 now := tmtime.Now() 594 ctx.SetBlockHeader(abci.Header{Time: now}) 595 delCoins := sdk.NewCoins(newFooCoin(50)) 596 597 addr1 := sdk.AccAddress([]byte("addr1_______________")) 598 addrModule := sdk.AccAddress([]byte("moduleAcc___________")) 599 macc := app.AccountKeeper.NewAccountWithAddress(ctx, addrModule) // we don't need to define an actual module account bc we just need the address for testing 600 acc := app.AccountKeeper.NewAccountWithAddress(ctx, addr1) 601 602 require.Error(t, app.BankKeeper.UndelegateCoins(ctx, addrModule, addr1, delCoins)) 603 604 app.AccountKeeper.SetAccount(ctx, macc) 605 606 require.Error(t, app.BankKeeper.UndelegateCoins(ctx, addrModule, addr1, delCoins)) 607 app.AccountKeeper.SetAccount(ctx, acc) 608 609 require.Error(t, app.BankKeeper.UndelegateCoins(ctx, addrModule, addr1, delCoins)) 610 }