Unverified Commit 83c9d22c authored by Matt, Park's avatar Matt, Park Committed by GitHub
Browse files

Create Force Unlock Messages (#2733)


* Initial commit

* Support partial force unlocking

* Remove unnecessary test

* Add message server test

* Add tests for lockup keeper

* Bez and Roman's code review

* Fix lint

* Update proto/osmosis/lockup/params.proto

Co-authored-by: default avatarDev Ojha <ValarDragon@users.noreply.github.com>

* proto build

Co-authored-by: default avatarDev Ojha <ValarDragon@users.noreply.github.com>
parent 818babfe
Showing with 1353 additions and 47 deletions
+1353 -47
package apptesting
import (
sdk "github.com/cosmos/cosmos-sdk/types"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
gammtypes "github.com/osmosis-labs/osmosis/v12/x/gamm/types"
"github.com/osmosis-labs/osmosis/v12/x/superfluid/types"
)
func (s *KeeperTestHelper) SuperfluidDelegateToDefaultVal(sender sdk.AccAddress, poolId uint64, lockId uint64) error {
valAddr := s.SetupValidator(stakingtypes.Bonded)
poolDenom := gammtypes.GetPoolShareDenom(poolId)
err := s.App.SuperfluidKeeper.AddNewSuperfluidAsset(s.Ctx, types.SuperfluidAsset{
Denom: poolDenom,
AssetType: types.SuperfluidAssetTypeLPShare,
})
s.Require().NoError(err)
return s.App.SuperfluidKeeper.SuperfluidDelegate(s.Ctx, sender.String(), lockId, valAddr.String())
}
......@@ -255,7 +255,7 @@ func (appKeepers *AppKeepers) InitNormalKeepers(
// TODO: Visit why this needs to be deref'd
*appKeepers.AccountKeeper,
appKeepers.BankKeeper,
appKeepers.DistrKeeper)
appKeepers.DistrKeeper, appKeepers.GetSubspace(lockuptypes.ModuleName))
appKeepers.EpochsKeeper = epochskeeper.NewKeeper(appKeepers.keys[epochstypes.StoreKey])
......@@ -430,6 +430,7 @@ func (appKeepers *AppKeepers) initParamsKeeper(appCodec codec.BinaryCodec, legac
paramsKeeper.Subspace(ibchost.ModuleName)
paramsKeeper.Subspace(icahosttypes.SubModuleName)
paramsKeeper.Subspace(incentivestypes.ModuleName)
paramsKeeper.Subspace(lockuptypes.ModuleName)
paramsKeeper.Subspace(poolincentivestypes.ModuleName)
paramsKeeper.Subspace(superfluidtypes.ModuleName)
paramsKeeper.Subspace(gammtypes.ModuleName)
......
package v13
import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/module"
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
lockuptypes "github.com/osmosis-labs/osmosis/v12/x/lockup/types"
"github.com/osmosis-labs/osmosis/v12/app/keepers"
"github.com/osmosis-labs/osmosis/v12/app/upgrades"
)
func CreateUpgradeHandler(
mm *module.Manager,
configurator module.Configurator,
bpm upgrades.BaseAppParamManager,
keepers *keepers.AppKeepers,
) upgradetypes.UpgradeHandler {
return func(ctx sdk.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) {
keepers.LockupKeeper.SetParams(ctx, lockuptypes.DefaultParams())
return mm.RunMigrations(ctx, configurator, fromVM)
}
}
syntax = "proto3";
package osmosis.lockup;
import "gogoproto/gogo.proto";
option go_package = "github.com/osmosis-labs/osmosis/v12/x/lockup/types";
message Params {
repeated string force_unlock_allowed_addresses = 1
[ (gogoproto.moretags) = "yaml:\"force_unlock_allowed_address\"" ];
}
......@@ -19,6 +19,7 @@ service Msg {
rpc BeginUnlocking(MsgBeginUnlocking) returns (MsgBeginUnlockingResponse);
// MsgEditLockup edits the existing lockups by lock ID
rpc ExtendLockup(MsgExtendLockup) returns (MsgExtendLockupResponse);
rpc ForceUnlock(MsgForceUnlock) returns (MsgForceUnlockResponse);
}
message MsgLockTokens {
......@@ -71,3 +72,17 @@ message MsgExtendLockup {
}
message MsgExtendLockupResponse { bool success = 1; }
// MsgForceUnlock unlocks locks immediately for
// addresses registered via governance.
message MsgForceUnlock {
string owner = 1 [ (gogoproto.moretags) = "yaml:\"owner\"" ];
uint64 ID = 2;
// Amount of unlocking coins. Unlock all if not set.
repeated cosmos.base.v1beta1.Coin coins = 3 [
(gogoproto.nullable) = false,
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"
];
}
message MsgForceUnlockResponse { bool success = 1; }
\ No newline at end of file
......@@ -8,6 +8,7 @@ import (
"github.com/osmosis-labs/osmosis/v12/x/lockup/types"
sdk "github.com/cosmos/cosmos-sdk/types"
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
)
// Keeper provides a way to manage module storage.
......@@ -16,21 +17,44 @@ type Keeper struct {
hooks types.LockupHooks
paramSpace paramtypes.Subspace
ak types.AccountKeeper
bk types.BankKeeper
ck types.CommunityPoolKeeper
}
// NewKeeper returns an instance of Keeper.
func NewKeeper(storeKey sdk.StoreKey, ak types.AccountKeeper, bk types.BankKeeper, ck types.CommunityPoolKeeper) *Keeper {
func NewKeeper(storeKey sdk.StoreKey, ak types.AccountKeeper, bk types.BankKeeper, ck types.CommunityPoolKeeper, paramSpace paramtypes.Subspace) *Keeper {
// set KeyTable if it has not already been set
if !paramSpace.HasKeyTable() {
paramSpace = paramSpace.WithKeyTable(types.ParamKeyTable())
}
return &Keeper{
storeKey: storeKey,
ak: ak,
bk: bk,
ck: ck,
storeKey: storeKey,
paramSpace: paramSpace,
ak: ak,
bk: bk,
ck: ck,
}
}
// GetParams returns the total set of lockup parameters.
func (k Keeper) GetParams(ctx sdk.Context) (params types.Params) {
k.paramSpace.GetParamSet(ctx, &params)
return params
}
// SetParams sets the total set of lockup parameters.
func (k Keeper) SetParams(ctx sdk.Context, params types.Params) {
k.paramSpace.SetParamSet(ctx, &params)
}
func (k Keeper) GetForceUnlockAllowedAddresses(ctx sdk.Context) (forceUnlockAllowedAddresses []string) {
return k.GetParams(ctx).ForceUnlockAllowedAddresses
}
// Logger returns a logger instance.
func (k Keeper) Logger(ctx sdk.Context) log.Logger {
return ctx.Logger().With("module", fmt.Sprintf("x/%s", types.ModuleName))
......
......@@ -22,6 +22,14 @@ type KeeperTestSuite struct {
func (suite *KeeperTestSuite) SetupTest() {
suite.Setup()
suite.querier = keeper.NewQuerier(*suite.App.LockupKeeper)
unbondingDuration := suite.App.StakingKeeper.GetParams(suite.Ctx).UnbondingTime
suite.App.IncentivesKeeper.SetLockableDurations(suite.Ctx, []time.Duration{
time.Hour * 24 * 14,
time.Hour,
time.Hour * 3,
time.Hour * 7,
unbondingDuration,
})
}
func (suite *KeeperTestSuite) SetupTestWithLevelDb() {
......
......@@ -205,7 +205,7 @@ func (k Keeper) beginUnlock(ctx sdk.Context, lock types.PeriodLock, coins sdk.Co
// Otherwise, split the lock into two locks, and fully unlock the newly created lock.
// (By virtue, the newly created lock we split into should have the unlock amount)
if len(coins) != 0 && !coins.IsEqual(lock.Coins) {
splitLock, err := k.splitLock(ctx, lock, coins)
splitLock, err := k.splitLock(ctx, lock, coins, false)
if err != nil {
return err
}
......@@ -307,6 +307,28 @@ func (k Keeper) UnlockMaturedLock(ctx sdk.Context, lockID uint64) error {
return k.unlockMaturedLockInternalLogic(ctx, *lock)
}
// PartialForceUnlock begins partial ForceUnlock of given lock for the given amount of coins.
// ForceUnlocks the lock as a whole when provided coins are empty, or coin provided equals amount of coins in the lock.
// This also supports the case of lock in an unbonding status.
func (k Keeper) PartialForceUnlock(ctx sdk.Context, lock types.PeriodLock, coins sdk.Coins) error {
// sanity check
if !coins.IsAllLTE(lock.Coins) {
return fmt.Errorf("requested amount to unlock exceeds locked tokens")
}
// split lock to support partial force unlock.
// (By virtue, the newly created lock we split into should have the unlock amount)
if len(coins) != 0 && !coins.IsEqual(lock.Coins) {
splitLock, err := k.splitLock(ctx, lock, coins, true)
if err != nil {
return err
}
lock = splitLock
}
return k.ForceUnlock(ctx, lock)
}
// ForceUnlock ignores unlock duration and immediately unlocks the lock and refunds tokens to lock owner.
func (k Keeper) ForceUnlock(ctx sdk.Context, lock types.PeriodLock) error {
// Steps:
......@@ -658,20 +680,24 @@ func (k Keeper) deleteLock(ctx sdk.Context, id uint64) {
}
// splitLock splits a lock with the given amount, and stores split new lock to the state.
func (k Keeper) splitLock(ctx sdk.Context, lock types.PeriodLock, coins sdk.Coins) (types.PeriodLock, error) {
if lock.IsUnlocking() {
// Returns the new lock after modifying the state of the old lock.
func (k Keeper) splitLock(ctx sdk.Context, lock types.PeriodLock, coins sdk.Coins, forceUnlock bool) (types.PeriodLock, error) {
if !forceUnlock && lock.IsUnlocking() {
return types.PeriodLock{}, fmt.Errorf("cannot split unlocking lock")
}
lock.Coins = lock.Coins.Sub(coins)
err := k.setLock(ctx, lock)
if err != nil {
return types.PeriodLock{}, err
}
// create a new lock
splitLockID := k.GetLastLockID(ctx) + 1
k.SetLastLockID(ctx, splitLockID)
splitLock := types.NewPeriodLock(splitLockID, lock.OwnerAddress(), lock.Duration, lock.EndTime, coins)
err = k.setLock(ctx, splitLock)
return splitLock, err
}
......
......@@ -871,3 +871,123 @@ func (suite *KeeperTestSuite) TestEditLockup() {
})
suite.Require().Equal(int64(0), acc.Int64())
}
func (suite *KeeperTestSuite) TestForceUnlock() {
addr1 := sdk.AccAddress([]byte("addr1---------------"))
testCases := []struct {
name string
postLockSetup func()
}{
{
name: "happy path",
},
{
name: "superfluid staked",
postLockSetup: func() {
err := suite.App.LockupKeeper.CreateSyntheticLockup(suite.Ctx, 1, "testDenom", time.Minute, true)
suite.Require().NoError(err)
},
},
}
for _, tc := range testCases {
// set up test and create default lock
suite.SetupTest()
coinsToLock := sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(10000000)))
suite.FundAcc(addr1, sdk.NewCoins(coinsToLock...))
lock, err := suite.App.LockupKeeper.CreateLock(suite.Ctx, addr1, coinsToLock, time.Minute)
suite.Require().NoError(err)
// post lock setup
if tc.postLockSetup != nil {
tc.postLockSetup()
}
err = suite.App.LockupKeeper.ForceUnlock(suite.Ctx, lock)
suite.Require().NoError(err)
// check that accumulation store has decreased
accum := suite.App.LockupKeeper.GetPeriodLocksAccumulation(suite.Ctx, types.QueryCondition{
LockQueryType: types.ByDuration,
Denom: "foo",
Duration: time.Minute,
})
suite.Require().Equal(accum.String(), "0")
// check balance of lock account to confirm
balances := suite.App.BankKeeper.GetAllBalances(suite.Ctx, addr1)
suite.Require().Equal(balances, coinsToLock)
// if it was superfluid delegated lock,
// confirm that we don't have associated synth locks
synthLocks := suite.App.LockupKeeper.GetAllSyntheticLockupsByLockup(suite.Ctx, lock.ID)
suite.Require().Equal(0, len(synthLocks))
// check if lock is deleted by checking trying to get lock ID
_, err = suite.App.LockupKeeper.GetLockByID(suite.Ctx, lock.ID)
suite.Require().Error(err)
}
}
func (suite *KeeperTestSuite) TestPartialForceUnlock() {
addr1 := sdk.AccAddress([]byte("addr1---------------"))
defaultDenomToLock := "stake"
defaultAmountToLock := sdk.NewInt(10000000)
testCases := []struct {
name string
coinsToForceUnlock sdk.Coins
expectedPass bool
}{
{
name: "unlock full amount",
coinsToForceUnlock: sdk.Coins{sdk.NewCoin(defaultDenomToLock, defaultAmountToLock)},
expectedPass: true,
},
{
name: "partial unlock",
coinsToForceUnlock: sdk.Coins{sdk.NewCoin(defaultDenomToLock, defaultAmountToLock.Quo(sdk.NewInt(2)))},
expectedPass: true,
},
{
name: "unlock more than locked",
coinsToForceUnlock: sdk.Coins{sdk.NewCoin(defaultDenomToLock, defaultAmountToLock.Add(sdk.NewInt(2)))},
expectedPass: false,
},
{
name: "try unlocking with empty coins",
coinsToForceUnlock: sdk.Coins{},
expectedPass: true,
},
}
for _, tc := range testCases {
// set up test and create default lock
suite.SetupTest()
coinsToLock := sdk.NewCoins(sdk.NewCoin("stake", defaultAmountToLock))
suite.FundAcc(addr1, sdk.NewCoins(coinsToLock...))
// balanceBeforeLock := suite.App.BankKeeper.GetAllBalances(suite.Ctx, addr1)
lock, err := suite.App.LockupKeeper.CreateLock(suite.Ctx, addr1, coinsToLock, time.Minute)
suite.Require().NoError(err)
err = suite.App.LockupKeeper.PartialForceUnlock(suite.Ctx, lock, tc.coinsToForceUnlock)
if tc.expectedPass {
suite.Require().NoError(err)
// check balance
balanceAfterForceUnlock := suite.App.BankKeeper.GetBalance(suite.Ctx, addr1, "stake")
if tc.coinsToForceUnlock.Empty() {
tc.coinsToForceUnlock = coinsToLock
}
suite.Require().Equal(tc.coinsToForceUnlock, sdk.Coins{balanceAfterForceUnlock})
} else {
suite.Require().Error(err)
// check balance
balanceAfterForceUnlock := suite.App.BankKeeper.GetBalance(suite.Ctx, addr1, "stake")
suite.Require().Equal(sdk.NewInt(0), balanceAfterForceUnlock.Amount)
}
}
}
......@@ -182,3 +182,43 @@ func (server msgServer) ExtendLockup(goCtx context.Context, msg *types.MsgExtend
return &types.MsgExtendLockupResponse{}, nil
}
// ForceUnlock ignores unlock duration and immediately unlocks the lock.
// This message is only allowed for governance-passed accounts that are kept as parameter in the lockup module.
// Locks that has been superfluid delegated is not supported.
func (server msgServer) ForceUnlock(goCtx context.Context, msg *types.MsgForceUnlock) (*types.MsgForceUnlockResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)
// check for chain parameter that the address is allowed to force unlock
forceUnlockAllowedAddresses := server.keeper.GetParams(ctx).ForceUnlockAllowedAddresses
found := false
for _, address := range forceUnlockAllowedAddresses {
if address == msg.Owner {
found = true
}
}
if !found {
return &types.MsgForceUnlockResponse{Success: false}, sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, "Sender (%s) not allowed to force unlock", msg.Owner)
}
lock, err := server.keeper.GetLockByID(ctx, msg.ID)
if err != nil {
return &types.MsgForceUnlockResponse{Success: false}, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, err.Error())
}
// check that given lock is not superfluid staked
synthLocks := server.keeper.GetAllSyntheticLockupsByLockup(ctx, lock.ID)
if len(synthLocks) > 0 {
return &types.MsgForceUnlockResponse{Success: false}, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "superfluid delegation exists for lock")
}
// force unlock given lock
// This also supports the case of force unlocking lock as a whole when msg.Coins
// provided is empty.
err = server.keeper.PartialForceUnlock(ctx, *lock, msg.Coins)
if err != nil {
return &types.MsgForceUnlockResponse{Success: false}, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, err.Error())
}
return &types.MsgForceUnlockResponse{Success: true}, nil
}
......@@ -3,6 +3,7 @@ package keeper_test
import (
"time"
gammtypes "github.com/osmosis-labs/osmosis/v12/x/gamm/types"
"github.com/osmosis-labs/osmosis/v12/x/lockup/keeper"
"github.com/osmosis-labs/osmosis/v12/x/lockup/types"
......@@ -327,3 +328,120 @@ func (suite *KeeperTestSuite) TestMsgEditLockup() {
}
}
}
func (suite *KeeperTestSuite) TestMsgForceUnlock() {
addr1 := sdk.AccAddress([]byte("addr1---------------"))
addr2 := sdk.AccAddress([]byte("addr2---------------"))
defaultPoolID, defaultLockID := uint64(1), uint64(1)
defaultLockAmount := sdk.NewInt(1000000000)
tests := []struct {
name string
forceUnlockAllowedAddress types.Params
postLockSetup func()
forceUnlockAmount sdk.Int
expectPass bool
}{
{
"happy path",
types.Params{ForceUnlockAllowedAddresses: []string{addr1.String()}},
func() {},
defaultLockAmount,
true,
},
{
"force unlock superfluid delegated lock",
types.Params{ForceUnlockAllowedAddresses: []string{addr1.String()}},
func() {
err := suite.SuperfluidDelegateToDefaultVal(addr1, defaultPoolID, defaultLockID)
suite.Require().NoError(err)
},
defaultLockAmount,
false,
},
{
"superfluid undelegating lock",
types.Params{ForceUnlockAllowedAddresses: []string{addr1.String()}},
func() {
err := suite.SuperfluidDelegateToDefaultVal(addr1, defaultPoolID, defaultLockID)
suite.Require().NoError(err)
err = suite.App.SuperfluidKeeper.SuperfluidUndelegate(suite.Ctx, addr1.String(), defaultLockID)
suite.Require().NoError(err)
},
defaultLockAmount,
false,
},
{
"partial unlock",
types.Params{ForceUnlockAllowedAddresses: []string{addr1.String()}},
func() {},
// try force unlocking half of locked amount
defaultLockAmount.Quo(sdk.NewInt(2)),
true,
},
{
"force unlock more than what we have locked",
types.Params{ForceUnlockAllowedAddresses: []string{addr1.String()}},
func() {},
// try force more than the locked amount
defaultLockAmount.Add(sdk.NewInt(1)),
false,
},
{
"params with different address",
types.Params{ForceUnlockAllowedAddresses: []string{addr2.String()}},
func() {},
defaultLockAmount,
false,
},
{
"param with multiple addresses ",
types.Params{ForceUnlockAllowedAddresses: []string{addr1.String(), addr2.String()}},
func() {},
defaultLockAmount,
true,
},
}
for _, test := range tests {
// set up test
suite.SetupTest()
suite.App.LockupKeeper.SetParams(suite.Ctx, test.forceUnlockAllowedAddress)
// prepare pool for superfluid staking cases
poolId := suite.PrepareBalancerPoolWithCoins(sdk.NewCoin("stake", sdk.NewInt(1000000000000)), sdk.NewCoin("foo", sdk.NewInt(5000)))
// lock tokens
msgServer := keeper.NewMsgServerImpl(suite.App.LockupKeeper)
c := sdk.WrapSDKContext(suite.Ctx)
poolDenom := gammtypes.GetPoolShareDenom(poolId)
coinsToLock := sdk.Coins{sdk.NewCoin(poolDenom, defaultLockAmount)}
suite.FundAcc(addr1, coinsToLock)
unbondingDuration := suite.App.StakingKeeper.GetParams(suite.Ctx).UnbondingTime
resp, err := msgServer.LockTokens(c, types.NewMsgLockTokens(addr1, unbondingDuration, coinsToLock))
suite.Require().NoError(err)
// setup env after lock tokens
test.postLockSetup()
// test force unlock
_, err = msgServer.ForceUnlock(c, types.NewMsgForceUnlock(addr1, resp.ID, sdk.Coins{sdk.NewCoin(poolDenom, test.forceUnlockAmount)}))
if test.expectPass {
suite.Require().NoError(err)
// check that we have successfully force unlocked
balanceAfterForceUnlock := suite.App.BankKeeper.GetBalance(suite.Ctx, addr1, poolDenom)
suite.Require().Equal(test.forceUnlockAmount, balanceAfterForceUnlock.Amount)
} else {
suite.Require().Error(err)
// check that we have successfully force unlocked
balanceAfterForceUnlock := suite.App.BankKeeper.GetBalance(suite.Ctx, addr1, poolDenom)
suite.Require().NotEqual(test.forceUnlockAmount, balanceAfterForceUnlock.Amount)
return
}
}
}
......@@ -14,6 +14,7 @@ const (
TypeMsgBeginUnlockingAll = "begin_unlocking_all"
TypeMsgBeginUnlocking = "begin_unlocking"
TypeMsgExtendLockup = "edit_lockup"
TypeForceUnlock = "force_unlock"
)
var _ sdk.Msg = &MsgLockTokens{}
......@@ -165,3 +166,41 @@ func (m MsgExtendLockup) GetSigners() []sdk.AccAddress {
owner, _ := sdk.AccAddressFromBech32(m.Owner)
return []sdk.AccAddress{owner}
}
var _ sdk.Msg = &MsgForceUnlock{}
// NewMsgBeginUnlockingAll creates a message to begin unlocking tokens.
func NewMsgForceUnlock(owner sdk.AccAddress, id uint64, coins sdk.Coins) *MsgForceUnlock {
return &MsgForceUnlock{
Owner: owner.String(),
ID: id,
Coins: coins,
}
}
func (m MsgForceUnlock) Route() string { return RouterKey }
func (m MsgForceUnlock) Type() string { return TypeMsgBeginUnlockingAll }
func (m MsgForceUnlock) ValidateBasic() error {
_, err := sdk.AccAddressFromBech32(m.Owner)
if err != nil {
return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "Invalid owner address (%s)", err)
}
if m.ID <= 0 {
return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "lock id should be bigger than 1 (%s)", err)
}
if !m.Coins.IsValid() {
return sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, m.Coins.String())
}
return nil
}
func (m MsgForceUnlock) GetSignBytes() []byte {
return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&m))
}
func (m MsgForceUnlock) GetSigners() []sdk.AccAddress {
owner, _ := sdk.AccAddressFromBech32(m.Owner)
return []sdk.AccAddress{owner}
}
package types
import (
fmt "fmt"
sdk "github.com/cosmos/cosmos-sdk/types"
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
)
// Parameter store keys.
var (
KeyForceUnlockAllowedAddresses = []byte("ForceUnlockAllowedAddresses")
_ paramtypes.ParamSet = &Params{}
)
// ParamTable for lockup module.
func ParamKeyTable() paramtypes.KeyTable {
return paramtypes.NewKeyTable().RegisterParamSet(&Params{})
}
func NewParams(forceUnlockAllowedAddresses []string) Params {
return Params{
ForceUnlockAllowedAddresses: forceUnlockAllowedAddresses,
}
}
// DefaultParams returns default lockup module parameters.
func DefaultParams() Params {
return Params{
ForceUnlockAllowedAddresses: []string{},
}
}
// validate params.
func (p Params) Validate() error {
if err := validateAddresses(p.ForceUnlockAllowedAddresses); err != nil {
return err
}
return nil
}
// Implements params.ParamSet.
func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs {
return paramtypes.ParamSetPairs{
paramtypes.NewParamSetPair(KeyForceUnlockAllowedAddresses, &p.ForceUnlockAllowedAddresses, validateAddresses),
}
}
func validateAddresses(i interface{}) error {
addresses, ok := i.([]string)
if !ok {
return fmt.Errorf("invalid parameter type: %T", i)
}
for _, address := range addresses {
_, err := sdk.AccAddressFromBech32(address)
if err != nil {
return err
}
}
return nil
}
// Code generated by protoc-gen-gogo. DO NOT EDIT.
// source: osmosis/lockup/params.proto
package types
import (
fmt "fmt"
_ "github.com/gogo/protobuf/gogoproto"
proto "github.com/gogo/protobuf/proto"
io "io"
math "math"
math_bits "math/bits"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
type Params struct {
ForceUnlockAllowedAddresses []string `protobuf:"bytes,1,rep,name=force_unlock_allowed_addresses,json=forceUnlockAllowedAddresses,proto3" json:"force_unlock_allowed_addresses,omitempty" yaml:"force_unlock_allowed_address"`
}
func (m *Params) Reset() { *m = Params{} }
func (m *Params) String() string { return proto.CompactTextString(m) }
func (*Params) ProtoMessage() {}
func (*Params) Descriptor() ([]byte, []int) {
return fileDescriptor_4595e58f5e17053c, []int{0}
}
func (m *Params) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *Params) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_Params.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *Params) XXX_Merge(src proto.Message) {
xxx_messageInfo_Params.Merge(m, src)
}
func (m *Params) XXX_Size() int {
return m.Size()
}
func (m *Params) XXX_DiscardUnknown() {
xxx_messageInfo_Params.DiscardUnknown(m)
}
var xxx_messageInfo_Params proto.InternalMessageInfo
func (m *Params) GetForceUnlockAllowedAddresses() []string {
if m != nil {
return m.ForceUnlockAllowedAddresses
}
return nil
}
func init() {
proto.RegisterType((*Params)(nil), "osmosis.lockup.Params")
}
func init() { proto.RegisterFile("osmosis/lockup/params.proto", fileDescriptor_4595e58f5e17053c) }
var fileDescriptor_4595e58f5e17053c = []byte{
// 214 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0xce, 0x2f, 0xce, 0xcd,
0x2f, 0xce, 0x2c, 0xd6, 0xcf, 0xc9, 0x4f, 0xce, 0x2e, 0x2d, 0xd0, 0x2f, 0x48, 0x2c, 0x4a, 0xcc,
0x2d, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x83, 0x4a, 0xea, 0x41, 0x24, 0xa5, 0x44,
0xd2, 0xf3, 0xd3, 0xf3, 0xc1, 0x52, 0xfa, 0x20, 0x16, 0x44, 0x95, 0x52, 0x19, 0x17, 0x5b, 0x00,
0x58, 0x97, 0x50, 0x0e, 0x97, 0x5c, 0x5a, 0x7e, 0x51, 0x72, 0x6a, 0x7c, 0x69, 0x1e, 0x48, 0x47,
0x7c, 0x62, 0x4e, 0x4e, 0x7e, 0x79, 0x6a, 0x4a, 0x7c, 0x62, 0x4a, 0x4a, 0x51, 0x6a, 0x71, 0x71,
0x6a, 0xb1, 0x04, 0xa3, 0x02, 0xb3, 0x06, 0xa7, 0x93, 0xfa, 0xa7, 0x7b, 0xf2, 0xca, 0x95, 0x89,
0xb9, 0x39, 0x56, 0x4a, 0xf8, 0xd4, 0x2b, 0x05, 0x49, 0x83, 0xa5, 0x43, 0xc1, 0xb2, 0x8e, 0x10,
0x49, 0x47, 0x98, 0x59, 0x4e, 0x3e, 0x27, 0x1e, 0xc9, 0x31, 0x5e, 0x78, 0x24, 0xc7, 0xf8, 0xe0,
0x91, 0x1c, 0xe3, 0x84, 0xc7, 0x72, 0x0c, 0x17, 0x1e, 0xcb, 0x31, 0xdc, 0x78, 0x2c, 0xc7, 0x10,
0x65, 0x94, 0x9e, 0x59, 0x92, 0x51, 0x9a, 0xa4, 0x97, 0x9c, 0x9f, 0xab, 0x0f, 0xf5, 0x82, 0x6e,
0x4e, 0x62, 0x52, 0x31, 0x8c, 0xa3, 0x5f, 0x66, 0x68, 0xa4, 0x5f, 0x01, 0xf3, 0x72, 0x49, 0x65,
0x41, 0x6a, 0x71, 0x12, 0x1b, 0xd8, 0x33, 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0x7b, 0xec,
0x2b, 0x68, 0x11, 0x01, 0x00, 0x00,
}
func (m *Params) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *Params) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if len(m.ForceUnlockAllowedAddresses) > 0 {
for iNdEx := len(m.ForceUnlockAllowedAddresses) - 1; iNdEx >= 0; iNdEx-- {
i -= len(m.ForceUnlockAllowedAddresses[iNdEx])
copy(dAtA[i:], m.ForceUnlockAllowedAddresses[iNdEx])
i = encodeVarintParams(dAtA, i, uint64(len(m.ForceUnlockAllowedAddresses[iNdEx])))
i--
dAtA[i] = 0xa
}
}
return len(dAtA) - i, nil
}
func encodeVarintParams(dAtA []byte, offset int, v uint64) int {
offset -= sovParams(v)
base := offset
for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80)
v >>= 7
offset++
}
dAtA[offset] = uint8(v)
return base
}
func (m *Params) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
if len(m.ForceUnlockAllowedAddresses) > 0 {
for _, s := range m.ForceUnlockAllowedAddresses {
l = len(s)
n += 1 + l + sovParams(uint64(l))
}
}
return n
}
func sovParams(x uint64) (n int) {
return (math_bits.Len64(x|1) + 6) / 7
}
func sozParams(x uint64) (n int) {
return sovParams(uint64((x << 1) ^ uint64((int64(x) >> 63))))
}
func (m *Params) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowParams
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: Params: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: Params: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field ForceUnlockAllowedAddresses", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowParams
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthParams
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthParams
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.ForceUnlockAllowedAddresses = append(m.ForceUnlockAllowedAddresses, string(dAtA[iNdEx:postIndex]))
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipParams(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthParams
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skipParams(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0
depth := 0
for iNdEx < l {
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowParams
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
wireType := int(wire & 0x7)
switch wireType {
case 0:
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowParams
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
iNdEx++
if dAtA[iNdEx-1] < 0x80 {
break
}
}
case 1:
iNdEx += 8
case 2:
var length int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowParams
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
length |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if length < 0 {
return 0, ErrInvalidLengthParams
}
iNdEx += length
case 3:
depth++
case 4:
if depth == 0 {
return 0, ErrUnexpectedEndOfGroupParams
}
depth--
case 5:
iNdEx += 4
default:
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
}
if iNdEx < 0 {
return 0, ErrInvalidLengthParams
}
if depth == 0 {
return iNdEx, nil
}
}
return 0, io.ErrUnexpectedEOF
}
var (
ErrInvalidLengthParams = fmt.Errorf("proto: negative length found during unmarshaling")
ErrIntOverflowParams = fmt.Errorf("proto: integer overflow")
ErrUnexpectedEndOfGroupParams = fmt.Errorf("proto: unexpected end of group")
)
This diff is collapsed.
......@@ -2,6 +2,7 @@ package keeper
import (
"github.com/gogo/protobuf/proto"
lockuptypes "github.com/osmosis-labs/osmosis/v12/x/lockup/types"
"github.com/osmosis-labs/osmosis/v12/x/superfluid/types"
......
......@@ -2,6 +2,7 @@ package keeper
import (
"github.com/gogo/protobuf/proto"
gammtypes "github.com/osmosis-labs/osmosis/v12/x/gamm/types"
"github.com/osmosis-labs/osmosis/v12/x/superfluid/types"
......
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