From 17dd54441294fd4093645fb02c9221bb775634ec Mon Sep 17 00:00:00 2001 From: Sunny Aggarwal Date: Thu, 8 Apr 2021 18:22:47 -0400 Subject: [PATCH] added hooks for gamm and lockup --- app/app.go | 16 ++++++++++++++-- x/gamm/keeper/keeper.go | 13 +++++++++++++ x/gamm/keeper/pool_service.go | 14 ++++++++------ x/gamm/types/hooks.go | 20 ++++++++++++++++++++ x/lockup/keeper/keeper.go | 23 +++++++++++++++++++---- x/lockup/keeper/lock.go | 3 +++ x/lockup/spec/06_hooks.md | 6 +++--- x/lockup/types/hooks.go | 33 +++++++++++++++++++++++++++++++++ 8 files changed, 113 insertions(+), 15 deletions(-) create mode 100644 x/gamm/types/hooks.go create mode 100644 x/lockup/types/hooks.go diff --git a/app/app.go b/app/app.go index d1ee89fa899..314cef6edc3 100644 --- a/app/app.go +++ b/app/app.go @@ -319,8 +319,20 @@ func NewOsmosisApp( // If evidence needs to be handled for the app, set routes in router here and seal app.EvidenceKeeper = *evidenceKeeper - app.GAMMKeeper = gammkeeper.NewKeeper(appCodec, keys[gammtypes.StoreKey], app.AccountKeeper, app.BankKeeper) - app.LockupKeeper = *lockupkeeper.NewKeeper(appCodec, keys[lockuptypes.StoreKey], app.AccountKeeper, app.BankKeeper) + gammKeeper := gammkeeper.NewKeeper(appCodec, keys[gammtypes.StoreKey], app.AccountKeeper, app.BankKeeper) + lockupKeeper := lockupkeeper.NewKeeper(appCodec, keys[lockuptypes.StoreKey], app.AccountKeeper, app.BankKeeper) + + app.GAMMKeeper = *gammKeeper.SetHooks( + gammtypes.NewMultiGammHooks( + // insert gamm hooks receivers here + ), + ) + + app.LockupKeeper = *lockupKeeper.SetHooks( + lockuptypes.NewMultiLockupHooks( + // insert lockup hooks receivers here + ), + ) /**** Module Options ****/ diff --git a/x/gamm/keeper/keeper.go b/x/gamm/keeper/keeper.go index 7ab785cf4e9..0aed66491f5 100644 --- a/x/gamm/keeper/keeper.go +++ b/x/gamm/keeper/keeper.go @@ -24,6 +24,8 @@ type Keeper struct { storeKey sdk.StoreKey cdc codec.BinaryMarshaler + hooks types.GammHooks + // keepers accountKeeper types.AccountKeeper bankKeeper types.BankKeeper @@ -50,3 +52,14 @@ func NewKeeper(cdc codec.BinaryMarshaler, storeKey sdk.StoreKey, accountKeeper t bankKeeper: bankKeeper, } } + +// Set the gamm hooks +func (k *Keeper) SetHooks(gh types.GammHooks) *Keeper { + if k.hooks != nil { + panic("cannot set gamm hooks twice") + } + + k.hooks = gh + + return k +} diff --git a/x/gamm/keeper/pool_service.go b/x/gamm/keeper/pool_service.go index 165b5e719cf..271cbb8f4c1 100644 --- a/x/gamm/keeper/pool_service.go +++ b/x/gamm/keeper/pool_service.go @@ -91,6 +91,8 @@ func (k Keeper) CreatePool( return 0, err } + k.hooks.AfterPoolCreated(ctx, poolAcc.GetId()) + return poolAcc.GetId(), nil } @@ -246,14 +248,14 @@ func (k Keeper) JoinSwapShareAmountOut( return sdk.Int{}, types.ErrPoolLocked } - PoolAsset, err := poolAcc.GetPoolAsset(tokenInDenom) + poolAsset, err := poolAcc.GetPoolAsset(tokenInDenom) if err != nil { return sdk.Int{}, err } tokenInAmount = calcSingleInGivenPoolOut( - PoolAsset.Token.Amount.ToDec(), - PoolAsset.Weight.ToDec(), + poolAsset.Token.Amount.ToDec(), + poolAsset.Weight.ToDec(), poolAcc.GetTotalShare().Amount.ToDec(), poolAcc.GetTotalWeight().ToDec(), shareOutAmount.ToDec(), @@ -265,11 +267,11 @@ func (k Keeper) JoinSwapShareAmountOut( } if tokenInAmount.GT(tokenInMaxAmount) { - return sdk.Int{}, sdkerrors.Wrapf(types.ErrLimitMaxAmount, "%s token is larger than max amount", PoolAsset.Token.Denom) + return sdk.Int{}, sdkerrors.Wrapf(types.ErrLimitMaxAmount, "%s token is larger than max amount", poolAsset.Token.Denom) } - PoolAsset.Token.Amount = PoolAsset.Token.Amount.Add(tokenInAmount) - err = poolAcc.SetPoolAssets([]types.PoolAsset{PoolAsset}) + poolAsset.Token.Amount = poolAsset.Token.Amount.Add(tokenInAmount) + err = poolAcc.SetPoolAssets([]types.PoolAsset{poolAsset}) if err != nil { return sdk.Int{}, err } diff --git a/x/gamm/types/hooks.go b/x/gamm/types/hooks.go new file mode 100644 index 00000000000..dbf3080a7e6 --- /dev/null +++ b/x/gamm/types/hooks.go @@ -0,0 +1,20 @@ +package types + +import sdk "github.com/cosmos/cosmos-sdk/types" + +type GammHooks interface { + AfterPoolCreated(ctx sdk.Context, poolId uint64) +} + +// combine multiple gamm hooks, all hook functions are run in array sequence +type MultiGammHooks []GammHooks + +func NewMultiGammHooks(hooks ...GammHooks) MultiGammHooks { + return hooks +} + +func (h MultiGammHooks) AfterPoolCreated(ctx sdk.Context, poolId uint64) { + for i := range h { + h[i].AfterPoolCreated(ctx, poolId) + } +} diff --git a/x/lockup/keeper/keeper.go b/x/lockup/keeper/keeper.go index c93f7de5a00..b8ae743bcf8 100644 --- a/x/lockup/keeper/keeper.go +++ b/x/lockup/keeper/keeper.go @@ -15,8 +15,11 @@ import ( type Keeper struct { cdc codec.Marshaler storeKey sdk.StoreKey - ak authkeeper.AccountKeeper - bk types.BankKeeper + + hooks types.LockupHooks + + ak authkeeper.AccountKeeper + bk types.BankKeeper } // NewKeeper returns an instance of Keeper @@ -24,8 +27,9 @@ func NewKeeper(cdc codec.Marshaler, storeKey sdk.StoreKey, ak authkeeper.Account return &Keeper{ cdc: cdc, storeKey: storeKey, - ak: ak, - bk: bk, + + ak: ak, + bk: bk, } } @@ -34,6 +38,17 @@ func (k Keeper) Logger(ctx sdk.Context) log.Logger { return ctx.Logger().With("module", fmt.Sprintf("x/%s", types.ModuleName)) } +// Set the lockup hooks +func (k *Keeper) SetHooks(lh types.LockupHooks) *Keeper { + if k.hooks != nil { + panic("cannot set lockup hooks twice") + } + + k.hooks = lh + + return k +} + // AdminKeeper defines a god priviledge keeper functions to remove tokens from locks and create new locks // For the governance system of token pools, we want a "ragequit" feature // So governance changes will take 1 week to go into effect diff --git a/x/lockup/keeper/lock.go b/x/lockup/keeper/lock.go index 29caefa85da..282c97c0652 100644 --- a/x/lockup/keeper/lock.go +++ b/x/lockup/keeper/lock.go @@ -253,6 +253,8 @@ func (k Keeper) Lock(ctx sdk.Context, lock types.PeriodLock) error { return err } } + + k.hooks.OnTokenLocked(ctx, lock.Owner, lock.ID, lock.Coins, lock.Duration, lock.EndTime) return nil } @@ -306,5 +308,6 @@ func (k Keeper) Unlock(ctx sdk.Context, lock types.PeriodLock) error { return err } } + k.hooks.OnTokenUnlocked(ctx, lock.Owner, lock.ID, lock.Coins, lock.Duration, lock.EndTime) return nil } diff --git a/x/lockup/spec/06_hooks.md b/x/lockup/spec/06_hooks.md index 839eab6fadf..2159ed118b5 100644 --- a/x/lockup/spec/06_hooks.md +++ b/x/lockup/spec/06_hooks.md @@ -11,6 +11,6 @@ In this section we describe the "hooks" that `lockup` module provide for other m Upon successful coin lock/unlock, other modules might need to do few actions automatically instead of endblocker basis synchronization. ```go - onTokenLocked(address sdk.AccAddress, lockID uint64, amount sdk.Coins, lockDuration time.Duration, unlockTime time.Time) - onTokenUnlocked(address sdk.AccAddress, lockID uint64, amount sdk.Coins, lockDuration time.Duration, unlockTime time.Time) -``` + OnTokenLocked(ctx sdk.Context, address sdk.AccAddress, lockID uint64, amount sdk.Coins, lockDuration time.Duration, unlockTime time.Time) + OnTokenUnlocked(ctx sdk.Context, address sdk.AccAddress, lockID uint64, amount sdk.Coins, lockDuration time.Duration, unlockTime time.Time) +``` \ No newline at end of file diff --git a/x/lockup/types/hooks.go b/x/lockup/types/hooks.go new file mode 100644 index 00000000000..1a773a53a0d --- /dev/null +++ b/x/lockup/types/hooks.go @@ -0,0 +1,33 @@ +package types + +import ( + "time" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +type LockupHooks interface { + OnTokenLocked(ctx sdk.Context, address sdk.AccAddress, lockID uint64, amount sdk.Coins, lockDuration time.Duration, unlockTime time.Time) + OnTokenUnlocked(ctx sdk.Context, address sdk.AccAddress, lockID uint64, amount sdk.Coins, lockDuration time.Duration, unlockTime time.Time) +} + +var _ LockupHooks = MultiLockupHooks{} + +// combine multiple gamm hooks, all hook functions are run in array sequence +type MultiLockupHooks []LockupHooks + +func NewMultiLockupHooks(hooks ...LockupHooks) MultiLockupHooks { + return hooks +} + +func (h MultiLockupHooks) OnTokenLocked(ctx sdk.Context, address sdk.AccAddress, lockID uint64, amount sdk.Coins, lockDuration time.Duration, unlockTime time.Time) { + for i := range h { + h[i].OnTokenLocked(ctx, address, lockID, amount, lockDuration, unlockTime) + } +} + +func (h MultiLockupHooks) OnTokenUnlocked(ctx sdk.Context, address sdk.AccAddress, lockID uint64, amount sdk.Coins, lockDuration time.Duration, unlockTime time.Time) { + for i := range h { + h[i].OnTokenUnlocked(ctx, address, lockID, amount, lockDuration, unlockTime) + } +}