Unverified Commit f66106fc authored by Dev Ojha's avatar Dev Ojha Committed by GitHub
Browse files

Refactor lock methods (#842)

* Move lock.go functions into iterator.go, lock_refs.go and store.go

This makes the code more structured, and is a precursor to a subsequent commit
of trying to de-duplicate a lot of this logic to reduce API & bug surface

* Delete several ActionById methods on locks

* Delete legacy.go and upgrade_test.go

* remove code duplication in events, remove a return param from unlock all
parent ea2aedae
Showing with 75 additions and 469 deletions
+75 -469
......@@ -2,6 +2,7 @@ package keeper
import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/osmosis-labs/osmosis/x/lockup/types"
)
func (k Keeper) AddLockRefByKey(ctx sdk.Context, key []byte, lockID uint64) error {
......@@ -19,3 +20,7 @@ func (k Keeper) GetLockRefs(ctx sdk.Context, key []byte) []uint64 {
func (k Keeper) SyntheticCoins(coins sdk.Coins, suffix string) sdk.Coins {
return syntheticCoins(coins, suffix)
}
func (k Keeper) GetCoinsFromLocks(locks []types.PeriodLock) sdk.Coins {
return k.getCoinsFromLocks(locks)
}
......@@ -16,7 +16,7 @@ func (suite *KeeperTestSuite) LockTokens(addr sdk.AccAddress, coins sdk.Coins, d
}
func (suite *KeeperTestSuite) BeginUnlocking(addr sdk.AccAddress) {
_, _, err := suite.app.LockupKeeper.BeginUnlockAllNotUnlockings(suite.ctx, addr)
_, err := suite.app.LockupKeeper.BeginUnlockAllNotUnlockings(suite.ctx, addr)
suite.Require().NoError(err)
}
......
......@@ -195,21 +195,18 @@ func (k Keeper) unlockFromIterator(ctx sdk.Context, iterator db.Iterator) ([]typ
return locks, coins
}
func (k Keeper) beginUnlockFromIterator(ctx sdk.Context, iterator db.Iterator) ([]types.PeriodLock, sdk.Coins, error) {
func (k Keeper) beginUnlockFromIterator(ctx sdk.Context, iterator db.Iterator) ([]types.PeriodLock, error) {
// Note: this function is only used for an account
// and this has no conflicts with synthetic lockups
coins := sdk.Coins{}
locks := k.getLocksFromIterator(ctx, iterator)
for _, lock := range locks {
err := k.BeginUnlock(ctx, lock)
if err != nil {
return locks, coins, err
return locks, err
}
// sum up all coins begin unlocking
coins = coins.Add(lock.Coins...)
}
return locks, coins, nil
return locks, nil
}
func (k Keeper) getCoinsFromIterator(ctx sdk.Context, iterator db.Iterator) sdk.Coins {
......
package keeper
import (
"encoding/binary"
"encoding/json"
"fmt"
"time"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/gogo/protobuf/proto"
"github.com/osmosis-labs/osmosis/x/lockup/types"
db "github.com/tendermint/tm-db"
)
func legacyAccumulationKey(duration time.Duration, id uint64) []byte {
res := make([]byte, 16)
binary.BigEndian.PutUint64(res[:8], uint64(duration))
binary.BigEndian.PutUint64(res[8:], id)
return res
}
func findIndex(IDs []uint64, ID uint64) int {
for index, id := range IDs {
if id == ID {
return index
}
}
return -1
}
func removeValue(IDs []uint64, ID uint64) ([]uint64, int) {
index := findIndex(IDs, ID)
if index < 0 {
return IDs, index
}
IDs[index] = IDs[len(IDs)-1] // set last element to index
return IDs[:len(IDs)-1], index
}
// getLockRefs get lock IDs specified on the prefix and timestamp key
func (k Keeper) getLegacyLockRefs(ctx sdk.Context, key []byte) []uint64 {
store := ctx.KVStore(k.storeKey)
lockIDs := []uint64{}
if store.Has(key) {
bz := store.Get(key)
err := json.Unmarshal(bz, &lockIDs)
if err != nil {
panic(err)
}
}
return lockIDs
}
func (k Keeper) getLegacyLocksFromIterator(ctx sdk.Context, iterator db.Iterator) []types.PeriodLock {
locks := []types.PeriodLock{}
defer iterator.Close()
for ; iterator.Valid(); iterator.Next() {
lockIDs := []uint64{}
err := json.Unmarshal(iterator.Value(), &lockIDs)
if err != nil {
panic(err)
}
for _, lockID := range lockIDs {
lock, err := k.GetLockByID(ctx, lockID)
if err != nil {
panic(err)
}
locks = append(locks, *lock)
}
}
return locks
}
// GetLegacyPeriodLocks Returns the period locks on pool
func (k Keeper) GetLegacyPeriodLocks(ctx sdk.Context) ([]types.PeriodLock, error) {
maxID := int(k.GetLastLockID(ctx) + 1)
locks := make([]types.PeriodLock, 0, maxID)
store := ctx.KVStore(k.storeKey)
for lockID := 0; lockID < maxID; lockID++ {
if lockID%10000 == 0 {
ctx.Logger().Info(fmt.Sprintf("Fetched %d locks", lockID))
}
// Copy in GetLockByID logic, with optimizations for hotloop
lockKey := lockStoreKey(uint64(lockID))
if !store.Has(lockKey) {
continue
}
lock := types.PeriodLock{}
bz := store.Get(lockKey)
err := proto.Unmarshal(bz, &lock)
if err != nil {
return nil, err
}
locks = append(locks, lock)
}
return locks, nil
}
// addLockRefByKey append lock ID into an array associated to provided key
func (k Keeper) addLegacyLockRefByKey(ctx sdk.Context, key []byte, lockID uint64) error {
store := ctx.KVStore(k.storeKey)
lockIDs := k.getLegacyLockRefs(ctx, key)
if findIndex(lockIDs, lockID) > -1 {
return fmt.Errorf("lock with same ID exist: %d", lockID)
}
lockIDs = append(lockIDs, lockID)
bz, err := json.Marshal(lockIDs)
if err != nil {
return err
}
store.Set(key, bz)
return nil
}
// deleteLegacyLockRefByKey removes lock ID from an array associated to provided key
func (k Keeper) deleteLegacyLockRefByKey(ctx sdk.Context, key []byte, lockID uint64) error {
var index = -1
store := ctx.KVStore(k.storeKey)
lockIDs := k.getLegacyLockRefs(ctx, key)
lockIDs, index = removeValue(lockIDs, lockID)
if index < 0 {
return fmt.Errorf("specific lock with ID %d not found", lockID)
}
if len(lockIDs) == 0 {
if store.Has(key) {
store.Delete(key)
}
} else {
bz, err := json.Marshal(lockIDs)
if err != nil {
return err
}
store.Set(key, bz)
}
return nil
}
// LegacyLockTokens lock tokens from an account for specified duration
func (k Keeper) LegacyLockTokens(ctx sdk.Context, owner sdk.AccAddress, coins sdk.Coins, duration time.Duration) (types.PeriodLock, error) {
ID := k.GetLastLockID(ctx) + 1
// unlock time is set at the beginning of unlocking time
lock := types.NewPeriodLock(ID, owner, duration, time.Time{}, coins)
return lock, k.LegacyLock(ctx, lock)
}
// Lock is a utility to lock coins into module account
func (k Keeper) LegacyLock(ctx sdk.Context, lock types.PeriodLock) error {
owner, err := sdk.AccAddressFromBech32(lock.Owner)
if err != nil {
return err
}
if err := k.bk.SendCoinsFromAccountToModule(ctx, owner, types.ModuleName, lock.Coins); err != nil {
return err
}
lockID := lock.ID
store := ctx.KVStore(k.storeKey)
bz, err := proto.Marshal(&lock)
if err != nil {
return err
}
store.Set(lockStoreKey(lockID), bz)
k.SetLastLockID(ctx, lockID)
refKeys, err := lockRefKeys(lock)
if err != nil {
return err
}
for _, refKey := range refKeys {
if err := k.addLegacyLockRefByKey(ctx, combineKeys(types.KeyPrefixNotUnlocking, refKey), lockID); err != nil {
return err
}
}
for _, coin := range lock.Coins {
k.accumulationStore(ctx, coin.Denom).Set(legacyAccumulationKey(lock.Duration, lock.ID), coin.Amount)
}
k.hooks.OnTokenLocked(ctx, owner, lock.ID, lock.Coins, lock.Duration, lock.EndTime)
return nil
}
// LegacyBeginUnlock is a utility to start unlocking coins from NotUnlocking queue
func (k Keeper) LegacyBeginUnlock(ctx sdk.Context, lock types.PeriodLock) error {
lockID := lock.ID
refKeys, err := lockRefKeys(lock)
if err != nil {
return err
}
for _, refKey := range refKeys {
err := k.deleteLegacyLockRefByKey(ctx, combineKeys(types.KeyPrefixNotUnlocking, refKey), lockID)
if err != nil {
return err
}
}
lock.EndTime = ctx.BlockTime().Add(lock.Duration)
store := ctx.KVStore(k.storeKey)
bz, err := proto.Marshal(&lock)
if err != nil {
return err
}
store.Set(lockStoreKey(lockID), bz)
refKeys, err = lockRefKeys(lock)
if err != nil {
return err
}
for _, refKey := range refKeys {
if err := k.addLegacyLockRefByKey(ctx, combineKeys(types.KeyPrefixUnlocking, refKey), lockID); err != nil {
return err
}
}
for _, coin := range lock.Coins {
k.accumulationStore(ctx, coin.Denom).Remove(legacyAccumulationKey(lock.Duration, lock.ID))
}
return nil
}
......@@ -55,29 +55,9 @@ func (k Keeper) GetPeriodLocksAccumulation(ctx sdk.Context, query types.QueryCon
}
// BeginUnlockAllNotUnlockings begins unlock for all not unlocking coins
func (k Keeper) BeginUnlockAllNotUnlockings(ctx sdk.Context, account sdk.AccAddress) ([]types.PeriodLock, sdk.Coins, error) {
locks, coins, err := k.beginUnlockFromIterator(ctx, k.AccountLockIterator(ctx, false, account))
return locks, coins, err
}
// BeginUnlockPeriodLockByID begin unlock by period lock ID
func (k Keeper) BeginUnlockPeriodLockByID(ctx sdk.Context, LockID uint64) (*types.PeriodLock, error) {
lock, err := k.GetLockByID(ctx, LockID)
if err != nil {
return lock, err
}
err = k.BeginUnlock(ctx, *lock)
return lock, err
}
// UnlockPeriodLockByID unlock by period lock ID
func (k Keeper) UnlockPeriodLockByID(ctx sdk.Context, LockID uint64) (*types.PeriodLock, error) {
lock, err := k.GetLockByID(ctx, LockID)
if err != nil {
return lock, err
}
err = k.Unlock(ctx, *lock)
return lock, err
func (k Keeper) BeginUnlockAllNotUnlockings(ctx sdk.Context, account sdk.AccAddress) ([]types.PeriodLock, error) {
locks, err := k.beginUnlockFromIterator(ctx, k.AccountLockIterator(ctx, false, account))
return locks, err
}
func (k Keeper) addTokensToLock(ctx sdk.Context, lock *types.PeriodLock, coins sdk.Coins) error {
......@@ -474,11 +454,23 @@ func (k Keeper) Unlock(ctx sdk.Context, lock types.PeriodLock) error {
return fmt.Errorf("lock is not unlockable yet: %s >= %s", curTime.String(), lock.EndTime.String())
}
return k.unlock(ctx, lock)
return k.unlockInternalLogic(ctx, lock)
}
func (k Keeper) unlock(ctx sdk.Context, lock types.PeriodLock) error {
// ForceUnlock ignores unlock duration and immediately unlock and refund.
// CONTRACT: should be used only at the chain upgrade script
// TODO: Revisit for Superfluid Staking
func (k Keeper) ForceUnlock(ctx sdk.Context, lock types.PeriodLock) error {
if !lock.IsUnlocking() {
err := k.BeginUnlock(ctx, lock)
if err != nil {
return err
}
}
return k.unlockInternalLogic(ctx, lock)
}
func (k Keeper) unlockInternalLogic(ctx sdk.Context, lock types.PeriodLock) error {
owner, err := sdk.AccAddressFromBech32(lock.Owner)
if err != nil {
return err
......@@ -489,6 +481,7 @@ func (k Keeper) unlock(ctx sdk.Context, lock types.PeriodLock) error {
return err
}
// TODO: Should we refactor next several lines into a 'delete lock' method?
// remove lock from store object
store := ctx.KVStore(k.storeKey)
store.Delete(lockStoreKey(lock.ID))
......@@ -507,16 +500,3 @@ func (k Keeper) unlock(ctx sdk.Context, lock types.PeriodLock) error {
k.hooks.OnTokenUnlocked(ctx, owner, lock.ID, lock.Coins, lock.Duration, lock.EndTime)
return nil
}
// ForceUnlock ignores unlock duration and immediately unlock and refund.
// CONTRACT: should be used only at the chain upgrade script
// TODO: Revisit for Superfluid Staking
func (k Keeper) ForceUnlock(ctx sdk.Context, lock types.PeriodLock) error {
if !lock.IsUnlocking() {
err := k.BeginUnlock(ctx, lock)
if err != nil {
return err
}
}
return k.unlock(ctx, lock)
}
......@@ -29,10 +29,11 @@ func (suite *KeeperTestSuite) TestBeginUnlocking() { // test for all unlockable
suite.Require().Equal(locks[0].IsUnlocking(), false)
// begin unlock
locks, unlockCoins, err := suite.app.LockupKeeper.BeginUnlockAllNotUnlockings(suite.ctx, addr1)
locks, err = suite.app.LockupKeeper.BeginUnlockAllNotUnlockings(suite.ctx, addr1)
unlockedCoins := suite.app.LockupKeeper.GetCoinsFromLocks(locks)
suite.Require().NoError(err)
suite.Require().Len(locks, 1)
suite.Require().Equal(unlockCoins, coins)
suite.Require().Equal(unlockedCoins, coins)
suite.Require().Equal(locks[0].ID, uint64(1))
// check locks
......@@ -64,9 +65,8 @@ func (suite *KeeperTestSuite) TestBeginUnlockPeriodLock() {
suite.Require().Equal(locks[0].IsUnlocking(), false)
// begin unlock
lock1, err := suite.app.LockupKeeper.BeginUnlockPeriodLockByID(suite.ctx, 1)
err = suite.app.LockupKeeper.BeginUnlock(suite.ctx, locks[0])
suite.Require().NoError(err)
suite.Require().Equal(lock1.ID, uint64(1))
// check locks
locks, err = suite.app.LockupKeeper.GetPeriodLocks(suite.ctx)
......@@ -97,9 +97,10 @@ func (suite *KeeperTestSuite) TestGetPeriodLocks() {
func (suite *KeeperTestSuite) TestUnlockPeriodLockByID() {
suite.SetupTest()
now := suite.ctx.BlockTime()
lockKeeper := suite.app.LockupKeeper
// initial check
locks, err := suite.app.LockupKeeper.GetPeriodLocks(suite.ctx)
locks, err := lockKeeper.GetPeriodLocks(suite.ctx)
suite.Require().NoError(err)
suite.Require().Len(locks, 0)
......@@ -109,27 +110,34 @@ func (suite *KeeperTestSuite) TestUnlockPeriodLockByID() {
suite.LockTokens(addr1, coins, time.Second)
// unlock lock just now
lock1, err := suite.app.LockupKeeper.UnlockPeriodLockByID(suite.ctx, 1)
lock, err := lockKeeper.GetLockByID(suite.ctx, 1)
suite.Require().NoError(err)
err = lockKeeper.Unlock(suite.ctx, *lock)
suite.Require().Error(err)
suite.Require().Equal(lock1.ID, uint64(1))
// unlock lock after 1s before starting unlock
lock2, err := suite.app.LockupKeeper.UnlockPeriodLockByID(suite.ctx.WithBlockTime(now.Add(time.Second)), 1)
// move start time to 1 second in the future.
suite.ctx = suite.ctx.WithBlockTime(now.Add(time.Second))
// Try to finish unlocking a lock, before starting unlock.
lock, err = lockKeeper.GetLockByID(suite.ctx, 1)
suite.Require().NoError(err)
err = lockKeeper.Unlock(suite.ctx, *lock)
suite.Require().Error(err)
suite.Require().Equal(lock2.ID, uint64(1))
// begin unlock
lock3, err := suite.app.LockupKeeper.BeginUnlockPeriodLockByID(suite.ctx.WithBlockTime(now.Add(time.Second)), 1)
lock, err = lockKeeper.GetLockByID(suite.ctx, 1)
suite.Require().NoError(err)
err = lockKeeper.BeginUnlock(suite.ctx, *lock)
suite.Require().NoError(err)
suite.Require().Equal(lock3.ID, uint64(1))
// unlock 1s after begin unlock
lock4, err := suite.app.LockupKeeper.UnlockPeriodLockByID(suite.ctx.WithBlockTime(now.Add(time.Second*2)), 1)
lock, err = lockKeeper.GetLockByID(suite.ctx, 1)
suite.Require().NoError(err)
err = lockKeeper.Unlock(suite.ctx.WithBlockTime(now.Add(time.Second*2)), *lock)
suite.Require().NoError(err)
suite.Require().Equal(lock4.ID, uint64(1))
// check locks
locks, err = suite.app.LockupKeeper.GetPeriodLocks(suite.ctx)
locks, err = lockKeeper.GetPeriodLocks(suite.ctx)
suite.Require().NoError(err)
suite.Require().Len(locks, 0)
}
......@@ -340,10 +348,11 @@ func (suite *KeeperTestSuite) TestEndblockerWithdrawAllMaturedLockups() {
}
// begin unlock
locks, unlockCoins, err := suite.app.LockupKeeper.BeginUnlockAllNotUnlockings(suite.ctx, addr1)
locks, err = suite.app.LockupKeeper.BeginUnlockAllNotUnlockings(suite.ctx, addr1)
unlockedCoins := suite.app.LockupKeeper.GetCoinsFromLocks(locks)
suite.Require().NoError(err)
suite.Require().Len(locks, len(times))
suite.Require().Equal(unlockCoins, totalCoins)
suite.Require().Equal(unlockedCoins, totalCoins)
for i := 0; i < len(times); i++ {
suite.Require().Equal(locks[i].ID, uint64(i+1))
}
......
......@@ -50,6 +50,7 @@ func (server msgServer) LockTokens(goCtx context.Context, msg *types.MsgLockToke
return &types.MsgLockTokensResponse{}, nil
}
}
// TODO: Add a case here for blocking locking of multiple coin denoms
lock, err := server.keeper.LockTokens(ctx, owner, msg.Coins, msg.Duration)
if err != nil {
......@@ -73,7 +74,11 @@ func (server msgServer) LockTokens(goCtx context.Context, msg *types.MsgLockToke
func (server msgServer) BeginUnlocking(goCtx context.Context, msg *types.MsgBeginUnlocking) (*types.MsgBeginUnlockingResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)
lock, err := server.keeper.BeginUnlockPeriodLockByID(ctx, msg.ID)
lock, err := server.keeper.GetLockByID(ctx, msg.ID)
if err != nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, err.Error())
}
err = server.keeper.BeginUnlock(ctx, *lock)
if err != nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, err.Error())
}
......@@ -83,13 +88,7 @@ func (server msgServer) BeginUnlocking(goCtx context.Context, msg *types.MsgBegi
}
ctx.EventManager().EmitEvents(sdk.Events{
sdk.NewEvent(
types.TypeEvtBeginUnlock,
sdk.NewAttribute(types.AttributePeriodLockID, utils.Uint64ToString(lock.ID)),
sdk.NewAttribute(types.AttributePeriodLockOwner, lock.Owner),
sdk.NewAttribute(types.AttributePeriodLockDuration, lock.Duration.String()),
sdk.NewAttribute(types.AttributePeriodLockUnlockTime, lock.EndTime.String()),
),
createBeginUnlockEvent(lock),
})
return &types.MsgBeginUnlockingResponse{}, nil
......@@ -103,29 +102,34 @@ func (server msgServer) BeginUnlockingAll(goCtx context.Context, msg *types.MsgB
return nil, err
}
unlocks, coins, err := server.keeper.BeginUnlockAllNotUnlockings(ctx, owner)
unlocks, err := server.keeper.BeginUnlockAllNotUnlockings(ctx, owner)
if err != nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, err.Error())
}
// Create the events for this message
unlockedCoins := server.keeper.getCoinsFromLocks(unlocks)
events := sdk.Events{
sdk.NewEvent(
types.TypeEvtBeginUnlockAll,
sdk.NewAttribute(types.AttributePeriodLockOwner, msg.Owner),
sdk.NewAttribute(types.AttributeUnlockedCoins, coins.String()),
sdk.NewAttribute(types.AttributeUnlockedCoins, unlockedCoins.String()),
),
}
for _, lock := range unlocks {
event := sdk.NewEvent(
types.TypeEvtBeginUnlock,
sdk.NewAttribute(types.AttributePeriodLockID, utils.Uint64ToString(lock.ID)),
sdk.NewAttribute(types.AttributePeriodLockOwner, lock.Owner),
sdk.NewAttribute(types.AttributePeriodLockDuration, lock.Duration.String()),
sdk.NewAttribute(types.AttributePeriodLockUnlockTime, lock.EndTime.String()),
)
events = events.AppendEvent(event)
events = events.AppendEvent(createBeginUnlockEvent(&lock))
}
ctx.EventManager().EmitEvents(events)
return &types.MsgBeginUnlockingAllResponse{}, nil
}
func createBeginUnlockEvent(lock *types.PeriodLock) sdk.Event {
return sdk.NewEvent(
types.TypeEvtBeginUnlock,
sdk.NewAttribute(types.AttributePeriodLockID, utils.Uint64ToString(lock.ID)),
sdk.NewAttribute(types.AttributePeriodLockOwner, lock.Owner),
sdk.NewAttribute(types.AttributePeriodLockDuration, lock.Duration.String()),
sdk.NewAttribute(types.AttributePeriodLockUnlockTime, lock.EndTime.String()),
)
}
package keeper_test
import (
"time"
"github.com/cosmos/cosmos-sdk/simapp"
sdk "github.com/cosmos/cosmos-sdk/types"
)
func (suite *KeeperTestSuite) LegacyLockTokens(addr sdk.AccAddress, coins sdk.Coins, duration time.Duration) {
err := simapp.FundAccount(suite.app.BankKeeper, suite.ctx, addr, coins)
suite.Require().NoError(err)
_, err = suite.app.LockupKeeper.LegacyLockTokens(suite.ctx, addr, coins, duration)
suite.Require().NoError(err)
}
// func (suite *KeeperTestSuite) TestUpgradeStoreManagement() {
// addr1 := sdk.AccAddress([]byte("addr1---------------"))
// addr2 := sdk.AccAddress([]byte("addr2---------------"))
// addr3 := sdk.AccAddress([]byte("addr3---------------"))
// testCases := []struct {
// msg string
// pre_update func()
// update func()
// post_update func()
// expPass bool
// }{
// {
// "with current upgrade plan",
// func() {
// coins := sdk.Coins{sdk.NewInt64Coin("stake", 10)}
// // lock coins
// suite.LegacyLockTokens(addr1, coins, 10*time.Second)
// suite.LegacyLockTokens(addr2, coins, 200*time.Second)
// suite.LegacyLockTokens(addr3, coins, 50*time.Second)
// // check locks
// locks, err := suite.app.LockupKeeper.GetLegacyPeriodLocks(suite.ctx)
// suite.Require().NoError(err)
// suite.Require().Len(locks, 3)
// // begin unlock
// err = suite.app.LockupKeeper.LegacyBeginUnlock(suite.ctx, locks[0])
// suite.Require().NoError(err)
// err = suite.app.LockupKeeper.LegacyBeginUnlock(suite.ctx, locks[2])
// suite.Require().NoError(err)
// },
// func() {
// // run block 20 seconds into future
// suite.app.BeginBlocker(suite.ctx, types.RequestBeginBlock{})
// suite.app.EndBlocker(suite.ctx, types.RequestEndBlock{suite.ctx.BlockHeight()})
// suite.ctx = suite.ctx.WithBlockTime(
// suite.ctx.BlockTime().Add(20 * time.Second))
// suite.app.BeginBlocker(suite.ctx, types.RequestBeginBlock{})
// suite.app.EndBlocker(suite.ctx, types.RequestEndBlock{suite.ctx.BlockHeight()})
// // mint coins to distribution module / community pool so prop12 upgrade doesn't panic
// var bal = int64(1000000000000)
// coin := sdk.NewInt64Coin("uosmo", bal)
// coins := sdk.NewCoins(coin)
// err := suite.app.BankKeeper.MintCoins(suite.ctx, "mint", coins)
// suite.Require().NoError(err)
// err = suite.app.BankKeeper.SendCoinsFromModuleToModule(suite.ctx, "mint", "distribution", coins)
// suite.Require().NoError(err)
// feePool := suite.app.DistrKeeper.GetFeePool(suite.ctx)
// feePool.CommunityPool = feePool.CommunityPool.Add(sdk.NewDecCoinFromCoin(coin))
// suite.app.DistrKeeper.SetFeePool(suite.ctx, feePool)
// // run upgrades
// plan := upgradetypes.Plan{Name: "v4", Height: 5}
// err = suite.app.UpgradeKeeper.ScheduleUpgrade(suite.ctx, plan)
// suite.Require().NoError(err)
// plan, exists := suite.app.UpgradeKeeper.GetUpgradePlan(suite.ctx)
// suite.Require().True(exists)
// suite.Assert().NotPanics(func() {
// suite.app.UpgradeKeeper.ApplyUpgrade(suite.ctx.WithBlockHeight(5), plan)
// })
// },
// func() {
// // check all queries just after upgrade
// locks, err := suite.app.LockupKeeper.GetPeriodLocks(suite.ctx)
// suite.Require().NoError(err)
// suite.Require().Len(locks, 3)
// // run a next block
// suite.ctx = suite.ctx.WithBlockHeight(6).WithBlockTime(suite.ctx.BlockTime().Add(5 * time.Second))
// suite.app.BeginBlocker(suite.ctx, types.RequestBeginBlock{})
// suite.app.EndBlocker(suite.ctx, types.RequestEndBlock{suite.ctx.BlockHeight()})
// // check all remainings
// locks, err = suite.app.LockupKeeper.GetPeriodLocks(suite.ctx)
// suite.Require().NoError(err)
// suite.Require().Len(locks, 2)
// // TODO: Update the rest of these queries
// locks = suite.app.LockupKeeper.GetAccountLockedPastTimeNotUnlockingOnly(suite.ctx, addr1, suite.ctx.BlockTime())
// suite.Require().Len(locks, 0)
// locks = suite.app.LockupKeeper.GetAccountUnlockedBeforeTime(suite.ctx, addr1, suite.ctx.BlockTime())
// suite.Require().Len(locks, 0)
// locks = suite.app.LockupKeeper.GetAccountLockedPastTimeDenom(suite.ctx, addr1, "stake", suite.ctx.BlockTime())
// suite.Require().Len(locks, 0)
// locks = suite.app.LockupKeeper.GetAccountLockedLongerDuration(suite.ctx, addr2, time.Second)
// suite.Require().Len(locks, 1)
// locks = suite.app.LockupKeeper.GetAccountLockedLongerDurationNotUnlockingOnly(suite.ctx, addr1, time.Second)
// suite.Require().Len(locks, 0)
// locks = suite.app.LockupKeeper.GetAccountLockedLongerDurationDenom(suite.ctx, addr2, "stake", time.Second)
// suite.Require().Len(locks, 1)
// locks = suite.app.LockupKeeper.GetLocksPastTimeDenom(suite.ctx, "stake", suite.ctx.BlockTime())
// suite.Require().Len(locks, 2)
// locks = suite.app.LockupKeeper.GetLocksLongerThanDurationDenom(suite.ctx, "stake", time.Second)
// suite.Require().Len(locks, 2)
// _, err = suite.app.LockupKeeper.GetLockByID(suite.ctx, 1)
// suite.Require().Error(err)
// _, err = suite.app.LockupKeeper.GetLockByID(suite.ctx, 2)
// suite.Require().NoError(err)
// locks = suite.app.LockupKeeper.GetAccountPeriodLocks(suite.ctx, addr1)
// suite.Require().Len(locks, 0)
// accum := suite.app.LockupKeeper.GetPeriodLocksAccumulation(suite.ctx, lockuptypes.QueryCondition{
// LockQueryType: lockuptypes.ByDuration,
// Denom: "stake",
// Duration: time.Second,
// })
// suite.Require().Equal(accum.String(), "20")
// accum = suite.app.LockupKeeper.GetPeriodLocksAccumulation(suite.ctx, lockuptypes.QueryCondition{
// LockQueryType: lockuptypes.ByDuration,
// Denom: "stake",
// Duration: 50 * time.Second,
// })
// suite.Require().Equal(accum.String(), "20")
// accum = suite.app.LockupKeeper.GetPeriodLocksAccumulation(suite.ctx, lockuptypes.QueryCondition{
// LockQueryType: lockuptypes.ByDuration,
// Denom: "stake",
// Duration: 200 * time.Second,
// })
// suite.Require().Equal(accum.String(), "10")
// },
// true,
// },
// }
// for _, tc := range testCases {
// suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
// suite.SetupTest() // reset
// tc.pre_update()
// tc.update()
// tc.post_update()
// })
// }
// }
......@@ -42,8 +42,6 @@ type Keeper interface {
GetPeriodLocks(sdk.Context) ([]types.PeriodLock, error)
// UnlockAllUnlockableCoins Unlock all unlockable coins
UnlockAllUnlockableCoins(sdk.Context, account sdk.AccAddress) (sdk.Coins, error)
// UnlockPeriodLockByID unlock by period lock ID
UnlockPeriodLockByID(sdk.Context, LockID uint64) (*types.PeriodLock, error)
// LockTokens lock tokens from an account for specified duration
LockTokens(sdk.Context, owner sdk.AccAddress, coins sdk.Coins, duration time.Duration) (types.PeriodLock, error)
// AddTokensToLock locks more tokens into a lockup
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment