github.com/Finschia/finschia-sdk@v0.49.1/x/auth/legacy/v043/store_test.go (about) 1 package v043_test 2 3 import ( 4 "fmt" 5 "testing" 6 "time" 7 8 "github.com/stretchr/testify/require" 9 tmproto "github.com/tendermint/tendermint/proto/tendermint/types" 10 11 "github.com/Finschia/finschia-sdk/simapp" 12 sdk "github.com/Finschia/finschia-sdk/types" 13 authkeeper "github.com/Finschia/finschia-sdk/x/auth/keeper" 14 authtypes "github.com/Finschia/finschia-sdk/x/auth/types" 15 "github.com/Finschia/finschia-sdk/x/auth/vesting/exported" 16 "github.com/Finschia/finschia-sdk/x/auth/vesting/types" 17 "github.com/Finschia/finschia-sdk/x/staking" 18 stakingkeeper "github.com/Finschia/finschia-sdk/x/staking/keeper" 19 stakingtypes "github.com/Finschia/finschia-sdk/x/staking/types" 20 ) 21 22 func TestMigrateVestingAccounts(t *testing.T) { 23 testCases := []struct { 24 name string 25 prepareFunc func(app *simapp.SimApp, ctx sdk.Context, validator stakingtypes.Validator, delegatorAddr sdk.AccAddress) 26 garbageFunc func(ctx sdk.Context, vesting exported.VestingAccount, app *simapp.SimApp) error 27 tokenAmount int64 28 expVested int64 29 expFree int64 30 blockTime int64 31 }{ 32 { 33 "delayed vesting has vested, multiple delegations less than the total account balance", 34 func(app *simapp.SimApp, ctx sdk.Context, validator stakingtypes.Validator, delegatorAddr sdk.AccAddress) { 35 baseAccount := authtypes.NewBaseAccountWithAddress(delegatorAddr) 36 vestedCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), sdk.NewInt(200))) 37 delayedAccount := types.NewDelayedVestingAccount(baseAccount, vestedCoins, ctx.BlockTime().Unix()) 38 39 ctx = ctx.WithBlockTime(ctx.BlockTime().AddDate(1, 0, 0)) 40 41 app.AccountKeeper.SetAccount(ctx, delayedAccount) 42 43 _, err := app.StakingKeeper.Delegate(ctx, delegatorAddr, sdk.NewInt(100), stakingtypes.Unbonded, validator, true) 44 require.NoError(t, err) 45 _, err = app.StakingKeeper.Delegate(ctx, delegatorAddr, sdk.NewInt(100), stakingtypes.Unbonded, validator, true) 46 require.NoError(t, err) 47 _, err = app.StakingKeeper.Delegate(ctx, delegatorAddr, sdk.NewInt(100), stakingtypes.Unbonded, validator, true) 48 require.NoError(t, err) 49 }, 50 cleartTrackingFields, 51 300, 52 0, 53 300, 54 0, 55 }, 56 { 57 "delayed vesting has vested, single delegations which exceed the vested amount", 58 func(app *simapp.SimApp, ctx sdk.Context, validator stakingtypes.Validator, delegatorAddr sdk.AccAddress) { 59 baseAccount := authtypes.NewBaseAccountWithAddress(delegatorAddr) 60 vestedCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), sdk.NewInt(200))) 61 delayedAccount := types.NewDelayedVestingAccount(baseAccount, vestedCoins, ctx.BlockTime().Unix()) 62 63 ctx = ctx.WithBlockTime(ctx.BlockTime().AddDate(1, 0, 0)) 64 65 app.AccountKeeper.SetAccount(ctx, delayedAccount) 66 67 _, err := app.StakingKeeper.Delegate(ctx, delegatorAddr, sdk.NewInt(300), stakingtypes.Unbonded, validator, true) 68 require.NoError(t, err) 69 }, 70 cleartTrackingFields, 71 300, 72 0, 73 300, 74 0, 75 }, 76 { 77 "delayed vesting has vested, multiple delegations which exceed the vested amount", 78 func(app *simapp.SimApp, ctx sdk.Context, validator stakingtypes.Validator, delegatorAddr sdk.AccAddress) { 79 baseAccount := authtypes.NewBaseAccountWithAddress(delegatorAddr) 80 vestedCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), sdk.NewInt(200))) 81 delayedAccount := types.NewDelayedVestingAccount(baseAccount, vestedCoins, ctx.BlockTime().Unix()) 82 83 ctx = ctx.WithBlockTime(ctx.BlockTime().AddDate(1, 0, 0)) 84 85 app.AccountKeeper.SetAccount(ctx, delayedAccount) 86 87 _, err := app.StakingKeeper.Delegate(ctx, delegatorAddr, sdk.NewInt(100), stakingtypes.Unbonded, validator, true) 88 require.NoError(t, err) 89 _, err = app.StakingKeeper.Delegate(ctx, delegatorAddr, sdk.NewInt(100), stakingtypes.Unbonded, validator, true) 90 require.NoError(t, err) 91 _, err = app.StakingKeeper.Delegate(ctx, delegatorAddr, sdk.NewInt(100), stakingtypes.Unbonded, validator, true) 92 require.NoError(t, err) 93 }, 94 cleartTrackingFields, 95 300, 96 0, 97 300, 98 0, 99 }, 100 { 101 "delayed vesting has not vested, single delegations which exceed the vested amount", 102 func(app *simapp.SimApp, ctx sdk.Context, validator stakingtypes.Validator, delegatorAddr sdk.AccAddress) { 103 baseAccount := authtypes.NewBaseAccountWithAddress(delegatorAddr) 104 vestedCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), sdk.NewInt(200))) 105 delayedAccount := types.NewDelayedVestingAccount(baseAccount, vestedCoins, ctx.BlockTime().AddDate(1, 0, 0).Unix()) 106 107 app.AccountKeeper.SetAccount(ctx, delayedAccount) 108 109 _, err := app.StakingKeeper.Delegate(ctx, delegatorAddr, sdk.NewInt(300), stakingtypes.Unbonded, validator, true) 110 require.NoError(t, err) 111 }, 112 cleartTrackingFields, 113 300, 114 200, 115 100, 116 0, 117 }, 118 { 119 "delayed vesting has not vested, multiple delegations which exceed the vested amount", 120 func(app *simapp.SimApp, ctx sdk.Context, validator stakingtypes.Validator, delegatorAddr sdk.AccAddress) { 121 baseAccount := authtypes.NewBaseAccountWithAddress(delegatorAddr) 122 vestedCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), sdk.NewInt(200))) 123 delayedAccount := types.NewDelayedVestingAccount(baseAccount, vestedCoins, ctx.BlockTime().AddDate(1, 0, 0).Unix()) 124 125 app.AccountKeeper.SetAccount(ctx, delayedAccount) 126 127 _, err := app.StakingKeeper.Delegate(ctx, delegatorAddr, sdk.NewInt(100), stakingtypes.Unbonded, validator, true) 128 require.NoError(t, err) 129 _, err = app.StakingKeeper.Delegate(ctx, delegatorAddr, sdk.NewInt(100), stakingtypes.Unbonded, validator, true) 130 require.NoError(t, err) 131 _, err = app.StakingKeeper.Delegate(ctx, delegatorAddr, sdk.NewInt(100), stakingtypes.Unbonded, validator, true) 132 require.NoError(t, err) 133 }, 134 cleartTrackingFields, 135 300, 136 200, 137 100, 138 0, 139 }, 140 { 141 "not end time", 142 func(app *simapp.SimApp, ctx sdk.Context, validator stakingtypes.Validator, delegatorAddr sdk.AccAddress) { 143 baseAccount := authtypes.NewBaseAccountWithAddress(delegatorAddr) 144 vestedCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), sdk.NewInt(300))) 145 delayedAccount := types.NewDelayedVestingAccount(baseAccount, vestedCoins, ctx.BlockTime().AddDate(1, 0, 0).Unix()) 146 147 app.AccountKeeper.SetAccount(ctx, delayedAccount) 148 149 _, err := app.StakingKeeper.Delegate(ctx, delegatorAddr, sdk.NewInt(100), stakingtypes.Unbonded, validator, true) 150 require.NoError(t, err) 151 _, err = app.StakingKeeper.Delegate(ctx, delegatorAddr, sdk.NewInt(100), stakingtypes.Unbonded, validator, true) 152 require.NoError(t, err) 153 _, err = app.StakingKeeper.Delegate(ctx, delegatorAddr, sdk.NewInt(100), stakingtypes.Unbonded, validator, true) 154 require.NoError(t, err) 155 }, 156 cleartTrackingFields, 157 300, 158 300, 159 0, 160 0, 161 }, 162 { 163 "delayed vesting has not vested, single delegation greater than the total account balance", 164 func(app *simapp.SimApp, ctx sdk.Context, validator stakingtypes.Validator, delegatorAddr sdk.AccAddress) { 165 baseAccount := authtypes.NewBaseAccountWithAddress(delegatorAddr) 166 vestedCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), sdk.NewInt(300))) 167 delayedAccount := types.NewDelayedVestingAccount(baseAccount, vestedCoins, ctx.BlockTime().AddDate(1, 0, 0).Unix()) 168 169 app.AccountKeeper.SetAccount(ctx, delayedAccount) 170 171 _, err := app.StakingKeeper.Delegate(ctx, delegatorAddr, sdk.NewInt(300), stakingtypes.Unbonded, validator, true) 172 require.NoError(t, err) 173 }, 174 cleartTrackingFields, 175 300, 176 300, 177 0, 178 0, 179 }, 180 { 181 "delayed vesting has vested, single delegation greater than the total account balance", 182 func(app *simapp.SimApp, ctx sdk.Context, validator stakingtypes.Validator, delegatorAddr sdk.AccAddress) { 183 baseAccount := authtypes.NewBaseAccountWithAddress(delegatorAddr) 184 vestedCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), sdk.NewInt(300))) 185 delayedAccount := types.NewDelayedVestingAccount(baseAccount, vestedCoins, ctx.BlockTime().Unix()) 186 187 ctx = ctx.WithBlockTime(ctx.BlockTime().AddDate(1, 0, 0)) 188 189 app.AccountKeeper.SetAccount(ctx, delayedAccount) 190 191 _, err := app.StakingKeeper.Delegate(ctx, delegatorAddr, sdk.NewInt(300), stakingtypes.Unbonded, validator, true) 192 require.NoError(t, err) 193 }, 194 cleartTrackingFields, 195 300, 196 0, 197 300, 198 0, 199 }, 200 { 201 "continuous vesting, start time after blocktime", 202 func(app *simapp.SimApp, ctx sdk.Context, validator stakingtypes.Validator, delegatorAddr sdk.AccAddress) { 203 startTime := ctx.BlockTime().AddDate(1, 0, 0).Unix() 204 endTime := ctx.BlockTime().AddDate(2, 0, 0).Unix() 205 baseAccount := authtypes.NewBaseAccountWithAddress(delegatorAddr) 206 vestedCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), sdk.NewInt(300))) 207 delayedAccount := types.NewContinuousVestingAccount(baseAccount, vestedCoins, startTime, endTime) 208 209 ctx = ctx.WithBlockTime(ctx.BlockTime().AddDate(1, 0, 0)) 210 211 app.AccountKeeper.SetAccount(ctx, delayedAccount) 212 213 _, err := app.StakingKeeper.Delegate(ctx, delegatorAddr, sdk.NewInt(300), stakingtypes.Unbonded, validator, true) 214 require.NoError(t, err) 215 }, 216 cleartTrackingFields, 217 300, 218 300, 219 0, 220 0, 221 }, 222 { 223 "continuous vesting, start time passed but not ended", 224 func(app *simapp.SimApp, ctx sdk.Context, validator stakingtypes.Validator, delegatorAddr sdk.AccAddress) { 225 startTime := ctx.BlockTime().AddDate(-1, 0, 0).Unix() 226 endTime := ctx.BlockTime().AddDate(2, 0, 0).Unix() 227 baseAccount := authtypes.NewBaseAccountWithAddress(delegatorAddr) 228 vestedCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), sdk.NewInt(300))) 229 delayedAccount := types.NewContinuousVestingAccount(baseAccount, vestedCoins, startTime, endTime) 230 231 ctx = ctx.WithBlockTime(ctx.BlockTime().AddDate(1, 0, 0)) 232 233 app.AccountKeeper.SetAccount(ctx, delayedAccount) 234 235 _, err := app.StakingKeeper.Delegate(ctx, delegatorAddr, sdk.NewInt(300), stakingtypes.Unbonded, validator, true) 236 require.NoError(t, err) 237 }, 238 cleartTrackingFields, 239 300, 240 200, 241 100, 242 0, 243 }, 244 { 245 "continuous vesting, start time and endtime passed", 246 func(app *simapp.SimApp, ctx sdk.Context, validator stakingtypes.Validator, delegatorAddr sdk.AccAddress) { 247 startTime := ctx.BlockTime().AddDate(-2, 0, 0).Unix() 248 endTime := ctx.BlockTime().AddDate(-1, 0, 0).Unix() 249 baseAccount := authtypes.NewBaseAccountWithAddress(delegatorAddr) 250 vestedCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), sdk.NewInt(300))) 251 delayedAccount := types.NewContinuousVestingAccount(baseAccount, vestedCoins, startTime, endTime) 252 253 ctx = ctx.WithBlockTime(ctx.BlockTime().AddDate(1, 0, 0)) 254 255 app.AccountKeeper.SetAccount(ctx, delayedAccount) 256 257 _, err := app.StakingKeeper.Delegate(ctx, delegatorAddr, sdk.NewInt(300), stakingtypes.Unbonded, validator, true) 258 require.NoError(t, err) 259 }, 260 cleartTrackingFields, 261 300, 262 0, 263 300, 264 0, 265 }, 266 { 267 "periodic vesting account, yet to be vested, some rewards delegated", 268 func(app *simapp.SimApp, ctx sdk.Context, validator stakingtypes.Validator, delegatorAddr sdk.AccAddress) { 269 baseAccount := authtypes.NewBaseAccountWithAddress(delegatorAddr) 270 vestedCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), sdk.NewInt(100))) 271 272 start := ctx.BlockTime().Unix() + int64(time.Hour/time.Second) 273 274 periods := []types.Period{ 275 { 276 Length: int64((24 * time.Hour) / time.Second), 277 Amount: vestedCoins, 278 }, 279 } 280 281 account := types.NewPeriodicVestingAccount(baseAccount, vestedCoins, start, periods) 282 283 app.AccountKeeper.SetAccount(ctx, account) 284 285 _, err := app.StakingKeeper.Delegate(ctx, delegatorAddr, sdk.NewInt(150), stakingtypes.Unbonded, validator, true) 286 require.NoError(t, err) 287 }, 288 cleartTrackingFields, 289 300, 290 100, 291 50, 292 0, 293 }, 294 { 295 "periodic vesting account, nothing has vested yet", 296 func(app *simapp.SimApp, ctx sdk.Context, validator stakingtypes.Validator, delegatorAddr sdk.AccAddress) { 297 /* 298 Test case: 299 - periodic vesting account starts at time 1601042400 300 - account balance and original vesting: 3666666670000 301 - nothing has vested, we put the block time slightly after start time 302 - expected vested: original vesting amount 303 - expected free: zero 304 - we're delegating the full original vesting 305 */ 306 startTime := int64(1601042400) 307 baseAccount := authtypes.NewBaseAccountWithAddress(delegatorAddr) 308 vestedCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), sdk.NewInt(3666666670000))) 309 periods := []types.Period{ 310 { 311 Length: 31536000, 312 Amount: sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), sdk.NewInt(1833333335000))), 313 }, 314 { 315 Length: 15638400, 316 Amount: sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), sdk.NewInt(916666667500))), 317 }, 318 { 319 Length: 15897600, 320 Amount: sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), sdk.NewInt(916666667500))), 321 }, 322 } 323 324 delayedAccount := types.NewPeriodicVestingAccount(baseAccount, vestedCoins, startTime, periods) 325 326 app.AccountKeeper.SetAccount(ctx, delayedAccount) 327 328 // delegation of the original vesting 329 _, err := app.StakingKeeper.Delegate(ctx, delegatorAddr, sdk.NewInt(3666666670000), stakingtypes.Unbonded, validator, true) 330 require.NoError(t, err) 331 }, 332 cleartTrackingFields, 333 3666666670000, 334 3666666670000, 335 0, 336 1601042400 + 1, 337 }, 338 { 339 "periodic vesting account, all has vested", 340 func(app *simapp.SimApp, ctx sdk.Context, validator stakingtypes.Validator, delegatorAddr sdk.AccAddress) { 341 /* 342 Test case: 343 - periodic vesting account starts at time 1601042400 344 - account balance and original vesting: 3666666670000 345 - all has vested, so we set the block time at initial time + sum of all periods times + 1 => 1601042400 + 31536000 + 15897600 + 15897600 + 1 346 - expected vested: zero 347 - expected free: original vesting amount 348 - we're delegating the full original vesting 349 */ 350 startTime := int64(1601042400) 351 baseAccount := authtypes.NewBaseAccountWithAddress(delegatorAddr) 352 vestedCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), sdk.NewInt(3666666670000))) 353 periods := []types.Period{ 354 { 355 Length: 31536000, 356 Amount: sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), sdk.NewInt(1833333335000))), 357 }, 358 { 359 Length: 15638400, 360 Amount: sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), sdk.NewInt(916666667500))), 361 }, 362 { 363 Length: 15897600, 364 Amount: sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), sdk.NewInt(916666667500))), 365 }, 366 } 367 368 delayedAccount := types.NewPeriodicVestingAccount(baseAccount, vestedCoins, startTime, periods) 369 370 ctx = ctx.WithBlockTime(time.Unix(1601042400+31536000+15897600+15897600+1, 0)) 371 372 app.AccountKeeper.SetAccount(ctx, delayedAccount) 373 374 // delegation of the original vesting 375 _, err := app.StakingKeeper.Delegate(ctx, delegatorAddr, sdk.NewInt(3666666670000), stakingtypes.Unbonded, validator, true) 376 require.NoError(t, err) 377 }, 378 cleartTrackingFields, 379 3666666670000, 380 0, 381 3666666670000, 382 1601042400 + 31536000 + 15897600 + 15897600 + 1, 383 }, 384 { 385 "periodic vesting account, first period has vested", 386 func(app *simapp.SimApp, ctx sdk.Context, validator stakingtypes.Validator, delegatorAddr sdk.AccAddress) { 387 /* 388 Test case: 389 - periodic vesting account starts at time 1601042400 390 - account balance and original vesting: 3666666670000 391 - first period have vested, so we set the block time at initial time + time of the first periods + 1 => 1601042400 + 31536000 + 1 392 - expected vested: original vesting - first period amount 393 - expected free: first period amount 394 - we're delegating the full original vesting 395 */ 396 startTime := int64(1601042400) 397 baseAccount := authtypes.NewBaseAccountWithAddress(delegatorAddr) 398 vestedCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), sdk.NewInt(3666666670000))) 399 periods := []types.Period{ 400 { 401 Length: 31536000, 402 Amount: sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), sdk.NewInt(1833333335000))), 403 }, 404 { 405 Length: 15638400, 406 Amount: sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), sdk.NewInt(916666667500))), 407 }, 408 { 409 Length: 15897600, 410 Amount: sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), sdk.NewInt(916666667500))), 411 }, 412 } 413 414 delayedAccount := types.NewPeriodicVestingAccount(baseAccount, vestedCoins, startTime, periods) 415 416 ctx = ctx.WithBlockTime(time.Unix(1601042400+31536000+1, 0)) 417 418 app.AccountKeeper.SetAccount(ctx, delayedAccount) 419 420 // delegation of the original vesting 421 _, err := app.StakingKeeper.Delegate(ctx, delegatorAddr, sdk.NewInt(3666666670000), stakingtypes.Unbonded, validator, true) 422 require.NoError(t, err) 423 }, 424 cleartTrackingFields, 425 3666666670000, 426 3666666670000 - 1833333335000, 427 1833333335000, 428 1601042400 + 31536000 + 1, 429 }, 430 { 431 "periodic vesting account, first 2 period has vested", 432 func(app *simapp.SimApp, ctx sdk.Context, validator stakingtypes.Validator, delegatorAddr sdk.AccAddress) { 433 /* 434 Test case: 435 - periodic vesting account starts at time 1601042400 436 - account balance and original vesting: 3666666670000 437 - first 2 periods have vested, so we set the block time at initial time + time of the two periods + 1 => 1601042400 + 31536000 + 15638400 + 1 438 - expected vested: original vesting - (sum of the first two periods amounts) 439 - expected free: sum of the first two periods 440 - we're delegating the full original vesting 441 */ 442 startTime := int64(1601042400) 443 baseAccount := authtypes.NewBaseAccountWithAddress(delegatorAddr) 444 vestedCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), sdk.NewInt(3666666670000))) 445 periods := []types.Period{ 446 { 447 Length: 31536000, 448 Amount: sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), sdk.NewInt(1833333335000))), 449 }, 450 { 451 Length: 15638400, 452 Amount: sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), sdk.NewInt(916666667500))), 453 }, 454 { 455 Length: 15897600, 456 Amount: sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), sdk.NewInt(916666667500))), 457 }, 458 } 459 460 delayedAccount := types.NewPeriodicVestingAccount(baseAccount, vestedCoins, startTime, periods) 461 462 ctx = ctx.WithBlockTime(time.Unix(1601042400+31536000+15638400+1, 0)) 463 464 app.AccountKeeper.SetAccount(ctx, delayedAccount) 465 466 // delegation of the original vesting 467 _, err := app.StakingKeeper.Delegate(ctx, delegatorAddr, sdk.NewInt(3666666670000), stakingtypes.Unbonded, validator, true) 468 require.NoError(t, err) 469 }, 470 cleartTrackingFields, 471 3666666670000, 472 3666666670000 - 1833333335000 - 916666667500, 473 1833333335000 + 916666667500, 474 1601042400 + 31536000 + 15638400 + 1, 475 }, 476 { 477 "vesting account has unbonding delegations in place", 478 func(app *simapp.SimApp, ctx sdk.Context, validator stakingtypes.Validator, delegatorAddr sdk.AccAddress) { 479 baseAccount := authtypes.NewBaseAccountWithAddress(delegatorAddr) 480 vestedCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), sdk.NewInt(300))) 481 482 delayedAccount := types.NewDelayedVestingAccount(baseAccount, vestedCoins, ctx.BlockTime().AddDate(10, 0, 0).Unix()) 483 484 app.AccountKeeper.SetAccount(ctx, delayedAccount) 485 486 // delegation of the original vesting 487 _, err := app.StakingKeeper.Delegate(ctx, delegatorAddr, sdk.NewInt(300), stakingtypes.Unbonded, validator, true) 488 require.NoError(t, err) 489 490 ctx = ctx.WithBlockTime(ctx.BlockTime().AddDate(1, 0, 0)) 491 492 valAddr, err := sdk.ValAddressFromBech32(validator.OperatorAddress) 493 require.NoError(t, err) 494 495 // un-delegation of the original vesting 496 _, err = app.StakingKeeper.Undelegate(ctx, delegatorAddr, valAddr, sdk.NewDecFromInt(sdk.NewInt(300))) 497 require.NoError(t, err) 498 }, 499 cleartTrackingFields, 500 450, 501 300, 502 0, 503 0, 504 }, 505 { 506 "vesting account has never delegated anything", 507 func(app *simapp.SimApp, ctx sdk.Context, validator stakingtypes.Validator, delegatorAddr sdk.AccAddress) { 508 baseAccount := authtypes.NewBaseAccountWithAddress(delegatorAddr) 509 vestedCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), sdk.NewInt(300))) 510 511 delayedAccount := types.NewDelayedVestingAccount(baseAccount, vestedCoins, ctx.BlockTime().AddDate(10, 0, 0).Unix()) 512 513 app.AccountKeeper.SetAccount(ctx, delayedAccount) 514 }, 515 cleartTrackingFields, 516 450, 517 0, 518 0, 519 0, 520 }, 521 { 522 "vesting account has no delegation but dirty DelegatedFree and DelegatedVesting fields", 523 func(app *simapp.SimApp, ctx sdk.Context, validator stakingtypes.Validator, delegatorAddr sdk.AccAddress) { 524 baseAccount := authtypes.NewBaseAccountWithAddress(delegatorAddr) 525 vestedCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), sdk.NewInt(300))) 526 527 delayedAccount := types.NewDelayedVestingAccount(baseAccount, vestedCoins, ctx.BlockTime().AddDate(10, 0, 0).Unix()) 528 529 app.AccountKeeper.SetAccount(ctx, delayedAccount) 530 }, 531 dirtyTrackingFields, 532 450, 533 0, 534 0, 535 0, 536 }, 537 } 538 539 for _, tc := range testCases { 540 t.Run(tc.name, func(t *testing.T) { 541 app := simapp.Setup(false) 542 ctx := app.BaseApp.NewContext(false, tmproto.Header{ 543 Time: time.Now(), 544 }) 545 546 addrs := simapp.AddTestAddrs(app, ctx, 1, sdk.NewInt(tc.tokenAmount)) 547 delegatorAddr := addrs[0] 548 549 _, valAddr := createValidator(t, ctx, app, tc.tokenAmount*2) 550 validator, found := app.StakingKeeper.GetValidator(ctx, valAddr) 551 require.True(t, found) 552 553 tc.prepareFunc(app, ctx, validator, delegatorAddr) 554 555 if tc.blockTime != 0 { 556 ctx = ctx.WithBlockTime(time.Unix(tc.blockTime, 0)) 557 } 558 559 // We introduce the bug 560 savedAccount := app.AccountKeeper.GetAccount(ctx, delegatorAddr) 561 vestingAccount, ok := savedAccount.(exported.VestingAccount) 562 require.True(t, ok) 563 require.NoError(t, tc.garbageFunc(ctx, vestingAccount, app)) 564 565 m := authkeeper.NewMigrator(app.AccountKeeper, app.GRPCQueryRouter()) 566 require.NoError(t, m.MigrateV040ToV043(ctx)) 567 568 var expVested sdk.Coins 569 var expFree sdk.Coins 570 571 if tc.expVested != 0 { 572 expVested = sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), sdk.NewInt(tc.expVested))) 573 } 574 575 if tc.expFree != 0 { 576 expFree = sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), sdk.NewInt(tc.expFree))) 577 } 578 579 trackingCorrected( 580 t, 581 ctx, 582 app.AccountKeeper, 583 savedAccount.GetAddress(), 584 expVested, 585 expFree, 586 ) 587 }) 588 } 589 } 590 591 func trackingCorrected(t *testing.T, ctx sdk.Context, ak authkeeper.AccountKeeper, addr sdk.AccAddress, expDelVesting, expDelFree sdk.Coins) { 592 t.Helper() 593 baseAccount := ak.GetAccount(ctx, addr) 594 vDA, ok := baseAccount.(exported.VestingAccount) 595 require.True(t, ok) 596 597 vestedOk := expDelVesting.Equal(vDA.GetDelegatedVesting()) 598 freeOk := expDelFree.Equal(vDA.GetDelegatedFree()) 599 require.True(t, vestedOk, vDA.GetDelegatedVesting().String()) 600 require.True(t, freeOk, vDA.GetDelegatedFree().String()) 601 } 602 603 func cleartTrackingFields(ctx sdk.Context, vesting exported.VestingAccount, app *simapp.SimApp) error { 604 switch t := vesting.(type) { 605 case *types.DelayedVestingAccount: 606 t.DelegatedFree = nil 607 t.DelegatedVesting = nil 608 app.AccountKeeper.SetAccount(ctx, t) 609 case *types.ContinuousVestingAccount: 610 t.DelegatedFree = nil 611 t.DelegatedVesting = nil 612 app.AccountKeeper.SetAccount(ctx, t) 613 case *types.PeriodicVestingAccount: 614 t.DelegatedFree = nil 615 t.DelegatedVesting = nil 616 app.AccountKeeper.SetAccount(ctx, t) 617 default: 618 return fmt.Errorf("expected vesting account, found %t", t) 619 } 620 621 return nil 622 } 623 624 func dirtyTrackingFields(ctx sdk.Context, vesting exported.VestingAccount, app *simapp.SimApp) error { 625 dirt := sdk.NewCoins(sdk.NewInt64Coin("stake", 42)) 626 627 switch t := vesting.(type) { 628 case *types.DelayedVestingAccount: 629 t.DelegatedFree = dirt 630 t.DelegatedVesting = dirt 631 app.AccountKeeper.SetAccount(ctx, t) 632 case *types.ContinuousVestingAccount: 633 t.DelegatedFree = dirt 634 t.DelegatedVesting = dirt 635 app.AccountKeeper.SetAccount(ctx, t) 636 case *types.PeriodicVestingAccount: 637 t.DelegatedFree = dirt 638 t.DelegatedVesting = dirt 639 app.AccountKeeper.SetAccount(ctx, t) 640 default: 641 return fmt.Errorf("expected vesting account, found %t", t) 642 } 643 644 return nil 645 } 646 647 func createValidator(t *testing.T, ctx sdk.Context, app *simapp.SimApp, powers int64) (sdk.AccAddress, sdk.ValAddress) { 648 t.Helper() 649 valTokens := sdk.TokensFromConsensusPower(powers, sdk.DefaultPowerReduction) 650 addrs := simapp.AddTestAddrsIncremental(app, ctx, 1, valTokens) 651 valAddrs := simapp.ConvertAddrsToValAddrs(addrs) 652 pks := simapp.CreateTestPubKeys(1) 653 cdc := simapp.MakeTestEncodingConfig().Marshaler 654 655 app.StakingKeeper = stakingkeeper.NewKeeper( 656 cdc, 657 app.GetKey(stakingtypes.StoreKey), 658 app.AccountKeeper, 659 app.BankKeeper, 660 app.GetSubspace(stakingtypes.ModuleName), 661 ) 662 663 val1, err := stakingtypes.NewValidator(valAddrs[0], pks[0], stakingtypes.Description{}) 664 require.NoError(t, err) 665 666 app.StakingKeeper.SetValidator(ctx, val1) 667 require.NoError(t, app.StakingKeeper.SetValidatorByConsAddr(ctx, val1)) 668 app.StakingKeeper.SetNewValidatorByPowerIndex(ctx, val1) 669 670 _, err = app.StakingKeeper.Delegate(ctx, addrs[0], valTokens, stakingtypes.Unbonded, val1, true) 671 require.NoError(t, err) 672 673 _ = staking.EndBlocker(ctx, app.StakingKeeper) 674 675 return addrs[0], valAddrs[0] 676 }