From d676cb01bfe6842c8c41b472bee728dc44b5a3ff Mon Sep 17 00:00:00 2001 From: jgo121 Date: Fri, 3 Nov 2023 20:41:48 +0800 Subject: [PATCH 1/8] automatic addition of staking tokens to staking basket when a new multistaking pool created after a validator join --- app/app.go | 12 ++-- proto/kira/basket/genesis.proto | 8 ++- x/basket/keeper/hooks.go | 77 ++++++++++++++++++++ x/basket/keeper/keeper.go | 5 +- x/basket/module.go | 2 + x/basket/types/expected_keepers.go | 6 ++ x/basket/types/genesis.go | 2 +- x/basket/types/genesis.pb.go | 90 +++++++++++++++++------- x/multistaking/keeper/delegation.go | 12 ++-- x/multistaking/keeper/keeper.go | 12 ++++ x/multistaking/keeper/msg_server.go | 10 ++- x/multistaking/keeper/pool.go | 22 ------ x/multistaking/keeper/slash.go | 2 + x/multistaking/types/expected_keepers.go | 5 ++ x/multistaking/types/hooks.go | 18 +++++ x/multistaking/types/pool.go | 27 +++++++ x/tokens/handler_test.go | 2 +- x/tokens/keeper/grpc_query.go | 2 +- x/tokens/keeper/rate.go | 6 +- x/tokens/keeper/rate_test.go | 6 +- x/tokens/module.go | 2 +- 21 files changed, 253 insertions(+), 75 deletions(-) create mode 100644 x/basket/keeper/hooks.go create mode 100644 x/multistaking/types/hooks.go create mode 100644 x/multistaking/types/pool.go diff --git a/app/app.go b/app/app.go index 8877ca25d..369af5ff0 100644 --- a/app/app.go +++ b/app/app.go @@ -271,12 +271,12 @@ func NewInitApp( app.TokensKeeper = tokenskeeper.NewKeeper(keys[tokenstypes.ModuleName], appCodec) app.CustomGovKeeper = customgovkeeper.NewKeeper(keys[govtypes.ModuleName], appCodec, app.BankKeeper) customStakingKeeper := customstakingkeeper.NewKeeper(keys[stakingtypes.ModuleName], cdc, app.CustomGovKeeper) - app.MultiStakingKeeper = multistakingkeeper.NewKeeper(keys[multistakingtypes.ModuleName], appCodec, app.BankKeeper, app.TokensKeeper, app.CustomGovKeeper, customStakingKeeper) + multiStakingKeeper := multistakingkeeper.NewKeeper(keys[multistakingtypes.ModuleName], appCodec, app.BankKeeper, app.TokensKeeper, app.CustomGovKeeper, customStakingKeeper) app.CustomSlashingKeeper = customslashingkeeper.NewKeeper( appCodec, keys[slashingtypes.StoreKey], &customStakingKeeper, - app.MultiStakingKeeper, + multiStakingKeeper, app.CustomGovKeeper, app.GetSubspace(slashingtypes.ModuleName), ) @@ -290,17 +290,21 @@ func NewInitApp( keys[baskettypes.ModuleName], appCodec, app.AccountKeeper, app.BankKeeper, app.CustomGovKeeper, - app.MultiStakingKeeper, + app.TokensKeeper, + multiStakingKeeper, ) app.CollectivesKeeper = collectiveskeeper.NewKeeper( keys[collectivestypes.StoreKey], appCodec, app.BankKeeper, app.CustomGovKeeper, - app.MultiStakingKeeper, + multiStakingKeeper, app.TokensKeeper, app.SpendingKeeper, ) + app.MultiStakingKeeper = *multiStakingKeeper.SetHooks( + multistakingtypes.NewMultiStakingHooks(app.BasketKeeper.Hooks()), + ) app.Layer2Keeper = layer2keeper.NewKeeper( keys[collectivestypes.StoreKey], appCodec, diff --git a/proto/kira/basket/genesis.proto b/proto/kira/basket/genesis.proto index 0782a9560..764fa9287 100644 --- a/proto/kira/basket/genesis.proto +++ b/proto/kira/basket/genesis.proto @@ -10,12 +10,14 @@ import "kira/basket/basket.proto"; message GenesisState { // baskets registered on the module repeated Basket baskets = 1 [ (gogoproto.nullable) = false ]; + // last basket id + uint64 last_basket_id = 2; // mints by time - repeated AmountAtTime historical_mints = 2 [ (gogoproto.nullable) = false ]; + repeated AmountAtTime historical_mints = 3 [ (gogoproto.nullable) = false ]; // burns by time - repeated AmountAtTime historical_burns = 3 [ (gogoproto.nullable) = false ]; + repeated AmountAtTime historical_burns = 4 [ (gogoproto.nullable) = false ]; // swaps by time - repeated AmountAtTime historical_swaps = 4 [ (gogoproto.nullable) = false ]; + repeated AmountAtTime historical_swaps = 5 [ (gogoproto.nullable) = false ]; } // https://www.notion.so/kira-network/KIP-78-Token-Basketing-Module-7e6da1f2667c4c13b2274d546031d5db \ No newline at end of file diff --git a/x/basket/keeper/hooks.go b/x/basket/keeper/hooks.go new file mode 100644 index 000000000..fe04d2c26 --- /dev/null +++ b/x/basket/keeper/hooks.go @@ -0,0 +1,77 @@ +package keeper + +import ( + "fmt" + + "github.com/KiraCore/sekai/x/basket/types" + multistakingtypes "github.com/KiraCore/sekai/x/multistaking/types" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +func (k Keeper) AfterUpsertStakingPool(ctx sdk.Context, valAddr sdk.ValAddress, pool multistakingtypes.StakingPool) { + rates := k.tk.GetAllTokenRates(ctx) + for _, rate := range rates { + if rate.StakeToken { + basket, err := k.GetBasketByDenom(ctx, fmt.Sprintf("sdb/%s", rate.Denom)) + if err != nil { + basket = types.Basket{ + Id: 1, + Suffix: fmt.Sprint("staking/%s", rate.Denom), + Description: fmt.Sprintf("Basket of staking derivatives for %s token", rate.Denom), + Amount: sdk.ZeroInt(), + SwapFee: sdk.ZeroDec(), + SlipppageFeeMin: sdk.ZeroDec(), + TokensCap: sdk.ZeroDec(), + LimitsPeriod: 86400, + MintsMin: sdk.OneInt(), + MintsMax: sdk.NewInt(1000_000_000_000), // 1M + MintsDisabled: false, + BurnsMin: sdk.OneInt(), + BurnsMax: sdk.NewInt(1000_000_000_000), // 1M + BurnsDisabled: false, + SwapsMin: sdk.OneInt(), + SwapsMax: sdk.NewInt(1000_000_000_000), // 1M + SwapsDisabled: false, + Tokens: []types.BasketToken{}, + Surplus: []sdk.Coin{}, + } + k.SetBasket(ctx, basket) + } + + shareDenom := multistakingtypes.GetShareDenom(pool.Id, rate.Denom) + tokenMap := make(map[string]bool) + for _, token := range basket.Tokens { + tokenMap[token.Denom] = true + } + if !tokenMap[shareDenom] { + basket.Tokens = append(basket.Tokens, types.BasketToken{ + Denom: shareDenom, + Weight: sdk.OneDec(), + Amount: sdk.ZeroInt(), + Deposits: true, + Withdraws: true, + Swaps: true, + }) + } + } + } +} + +//_________________________________________________________________________________________ + +// Hooks wrapper struct for multistaking keeper +type Hooks struct { + k Keeper +} + +var _ types.MultistakingHooks = Hooks{} + +// Return the wrapper struct +func (k Keeper) Hooks() Hooks { + return Hooks{k} +} + +// Implements sdk.ValidatorHooks +func (h Hooks) AfterUpsertStakingPool(ctx sdk.Context, valAddr sdk.ValAddress, pool multistakingtypes.StakingPool) { + h.k.AfterUpsertStakingPool(ctx, valAddr, pool) +} diff --git a/x/basket/keeper/keeper.go b/x/basket/keeper/keeper.go index edff2ac26..d63e275c9 100644 --- a/x/basket/keeper/keeper.go +++ b/x/basket/keeper/keeper.go @@ -4,6 +4,7 @@ import ( "github.com/KiraCore/sekai/x/basket/types" govkeeper "github.com/KiraCore/sekai/x/gov/keeper" govtypes "github.com/KiraCore/sekai/x/gov/types" + tokenskeeper "github.com/KiraCore/sekai/x/tokens/keeper" "github.com/cosmos/cosmos-sdk/codec" storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" @@ -16,17 +17,19 @@ type Keeper struct { ak types.AccountKeeper bk types.BankKeeper gk govkeeper.Keeper + tk tokenskeeper.Keeper mk types.MultiStakingKeeper } // NewKeeper returns instance of a keeper -func NewKeeper(storeKey storetypes.StoreKey, cdc codec.BinaryCodec, ak types.AccountKeeper, bk types.BankKeeper, gk govkeeper.Keeper, mk types.MultiStakingKeeper) Keeper { +func NewKeeper(storeKey storetypes.StoreKey, cdc codec.BinaryCodec, ak types.AccountKeeper, bk types.BankKeeper, gk govkeeper.Keeper, tk tokenskeeper.Keeper, mk types.MultiStakingKeeper) Keeper { return Keeper{ cdc: cdc, storeKey: storeKey, ak: ak, bk: bk, gk: gk, + tk: tk, mk: mk, } } diff --git a/x/basket/module.go b/x/basket/module.go index d9f0ad4bf..e94d4adb2 100644 --- a/x/basket/module.go +++ b/x/basket/module.go @@ -96,6 +96,7 @@ func (am AppModule) InitGenesis( var genesisState baskettypes.GenesisState cdc.MustUnmarshalJSON(data, &genesisState) + am.basketKeeper.SetLastBasketId(ctx, genesisState.LastBasketId) for _, basket := range genesisState.Baskets { am.basketKeeper.SetBasket(ctx, basket) } @@ -118,6 +119,7 @@ func (am AppModule) InitGenesis( func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawMessage { genesisState := baskettypes.GenesisState{ Baskets: am.basketKeeper.GetAllBaskets(ctx), + LastBasketId: am.basketKeeper.GetLastBasketId(ctx), HistoricalMints: am.basketKeeper.GetAllMintAmounts(ctx), HistoricalBurns: am.basketKeeper.GetAllBurnAmounts(ctx), HistoricalSwaps: am.basketKeeper.GetAllSwapAmounts(ctx), diff --git a/x/basket/types/expected_keepers.go b/x/basket/types/expected_keepers.go index 3e5d89c09..ad4698bc4 100644 --- a/x/basket/types/expected_keepers.go +++ b/x/basket/types/expected_keepers.go @@ -2,6 +2,7 @@ package types import ( govtypes "github.com/KiraCore/sekai/x/gov/types" + multistakingtypes "github.com/KiraCore/sekai/x/multistaking/types" sdk "github.com/cosmos/cosmos-sdk/types" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" ) @@ -28,3 +29,8 @@ type MultiStakingKeeper interface { ClaimRewards(ctx sdk.Context, delegator sdk.AccAddress) sdk.Coins ClaimRewardsFromModule(ctx sdk.Context, module string) sdk.Coins } + +// MultistakingHooks event hooks for multistaking +type MultistakingHooks interface { + AfterUpsertStakingPool(ctx sdk.Context, valAddr sdk.ValAddress, pool multistakingtypes.StakingPool) // Must be called when a upsert staking pool +} diff --git a/x/basket/types/genesis.go b/x/basket/types/genesis.go index fad64157c..146c3d9cc 100644 --- a/x/basket/types/genesis.go +++ b/x/basket/types/genesis.go @@ -1,6 +1,6 @@ package types -// DefaultGenesis returns the default CustomGo genesis state +// DefaultGenesis returns the default genesis state func DefaultGenesis() *GenesisState { return &GenesisState{} } diff --git a/x/basket/types/genesis.pb.go b/x/basket/types/genesis.pb.go index 2042bd093..967a3cf37 100644 --- a/x/basket/types/genesis.pb.go +++ b/x/basket/types/genesis.pb.go @@ -27,12 +27,14 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package type GenesisState struct { // baskets registered on the module Baskets []Basket `protobuf:"bytes,1,rep,name=baskets,proto3" json:"baskets"` + // last basket id + LastBasketId uint64 `protobuf:"varint,2,opt,name=last_basket_id,json=lastBasketId,proto3" json:"last_basket_id,omitempty"` // mints by time - HistoricalMints []AmountAtTime `protobuf:"bytes,2,rep,name=historical_mints,json=historicalMints,proto3" json:"historical_mints"` + HistoricalMints []AmountAtTime `protobuf:"bytes,3,rep,name=historical_mints,json=historicalMints,proto3" json:"historical_mints"` // burns by time - HistoricalBurns []AmountAtTime `protobuf:"bytes,3,rep,name=historical_burns,json=historicalBurns,proto3" json:"historical_burns"` + HistoricalBurns []AmountAtTime `protobuf:"bytes,4,rep,name=historical_burns,json=historicalBurns,proto3" json:"historical_burns"` // swaps by time - HistoricalSwaps []AmountAtTime `protobuf:"bytes,4,rep,name=historical_swaps,json=historicalSwaps,proto3" json:"historical_swaps"` + HistoricalSwaps []AmountAtTime `protobuf:"bytes,5,rep,name=historical_swaps,json=historicalSwaps,proto3" json:"historical_swaps"` } func (m *GenesisState) Reset() { *m = GenesisState{} } @@ -75,6 +77,13 @@ func (m *GenesisState) GetBaskets() []Basket { return nil } +func (m *GenesisState) GetLastBasketId() uint64 { + if m != nil { + return m.LastBasketId + } + return 0 +} + func (m *GenesisState) GetHistoricalMints() []AmountAtTime { if m != nil { return m.HistoricalMints @@ -103,24 +112,26 @@ func init() { func init() { proto.RegisterFile("kira/basket/genesis.proto", fileDescriptor_13d33dee654eeee6) } var fileDescriptor_13d33dee654eeee6 = []byte{ - // 268 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0xcc, 0xce, 0x2c, 0x4a, - 0xd4, 0x4f, 0x4a, 0x2c, 0xce, 0x4e, 0x2d, 0xd1, 0x4f, 0x4f, 0xcd, 0x4b, 0x2d, 0xce, 0x2c, 0xd6, - 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x06, 0x49, 0xe9, 0x41, 0xa4, 0xa4, 0x44, 0xd2, 0xf3, - 0xd3, 0xf3, 0xc1, 0xe2, 0xfa, 0x20, 0x16, 0x44, 0x89, 0x94, 0x04, 0xb2, 0x6e, 0x08, 0x05, 0x91, - 0x51, 0x5a, 0xce, 0xc4, 0xc5, 0xe3, 0x0e, 0x31, 0x2e, 0xb8, 0x24, 0xb1, 0x24, 0x55, 0xc8, 0x98, - 0x8b, 0x1d, 0xa2, 0xa0, 0x58, 0x82, 0x51, 0x81, 0x59, 0x83, 0xdb, 0x48, 0x58, 0x0f, 0xc9, 0x7c, - 0x3d, 0x27, 0x30, 0xe5, 0xc4, 0x72, 0xe2, 0x9e, 0x3c, 0x43, 0x10, 0x4c, 0xa5, 0x90, 0x17, 0x97, - 0x40, 0x46, 0x66, 0x71, 0x49, 0x7e, 0x51, 0x66, 0x72, 0x62, 0x4e, 0x7c, 0x6e, 0x66, 0x5e, 0x49, - 0xb1, 0x04, 0x13, 0x58, 0xb7, 0x24, 0x8a, 0x6e, 0xc7, 0xdc, 0xfc, 0xd2, 0xbc, 0x12, 0xc7, 0x92, - 0x90, 0xcc, 0xdc, 0x54, 0xa8, 0x19, 0xfc, 0x08, 0x8d, 0xbe, 0x20, 0x7d, 0x68, 0x66, 0x25, 0x95, - 0x16, 0xe5, 0x15, 0x4b, 0x30, 0x93, 0x6c, 0x96, 0x13, 0x48, 0x1f, 0x9a, 0x59, 0xc5, 0xe5, 0x89, - 0x05, 0xc5, 0x12, 0x2c, 0x24, 0x9b, 0x15, 0x0c, 0xd2, 0xe7, 0xe4, 0x74, 0xe2, 0x91, 0x1c, 0xe3, - 0x85, 0x47, 0x72, 0x8c, 0x0f, 0x1e, 0xc9, 0x31, 0x4e, 0x78, 0x2c, 0xc7, 0x70, 0xe1, 0xb1, 0x1c, - 0xc3, 0x8d, 0xc7, 0x72, 0x0c, 0x51, 0x1a, 0xe9, 0x99, 0x25, 0x19, 0xa5, 0x49, 0x7a, 0xc9, 0xf9, - 0xb9, 0xfa, 0xde, 0x99, 0x45, 0x89, 0xce, 0xf9, 0x45, 0xa9, 0xfa, 0xc5, 0xa9, 0xd9, 0x89, 0x99, - 0xfa, 0x15, 0xb0, 0x40, 0x2f, 0xa9, 0x2c, 0x48, 0x2d, 0x4e, 0x62, 0x03, 0x07, 0xba, 0x31, 0x20, - 0x00, 0x00, 0xff, 0xff, 0x4b, 0xdc, 0x27, 0xb6, 0xce, 0x01, 0x00, 0x00, + // 296 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x91, 0xb1, 0x4e, 0xc3, 0x30, + 0x10, 0x86, 0x93, 0xb6, 0x80, 0x94, 0x56, 0x80, 0x02, 0x83, 0xdb, 0xc1, 0x54, 0x88, 0xa1, 0x53, + 0x2c, 0xd1, 0x27, 0x68, 0x18, 0x10, 0x20, 0x96, 0x96, 0x89, 0xa5, 0x72, 0x5a, 0x2b, 0xb5, 0xd2, + 0xc4, 0x91, 0xef, 0x22, 0xe0, 0x2d, 0x78, 0xac, 0x2e, 0x48, 0x1d, 0x99, 0x10, 0x4a, 0x5e, 0x04, + 0x39, 0xa6, 0xa2, 0x74, 0xeb, 0x74, 0xf6, 0xdd, 0x7d, 0xdf, 0x3f, 0x9c, 0xd7, 0x4d, 0xa4, 0xe6, + 0x2c, 0xe2, 0x90, 0x08, 0x64, 0xb1, 0xc8, 0x04, 0x48, 0x08, 0x72, 0xad, 0x50, 0xf9, 0x6d, 0x33, + 0x0a, 0xec, 0xa8, 0x77, 0x1e, 0xab, 0x58, 0xd5, 0x7d, 0x66, 0x5e, 0x76, 0xa5, 0x47, 0xb6, 0x69, + 0x5b, 0xec, 0xe4, 0xf2, 0xa3, 0xe1, 0x75, 0x6e, 0xad, 0x6e, 0x82, 0x1c, 0x85, 0x3f, 0xf4, 0x8e, + 0xec, 0x02, 0x10, 0xb7, 0xdf, 0x1c, 0xb4, 0xaf, 0xcf, 0x82, 0x2d, 0x7f, 0x10, 0xd6, 0x25, 0x6c, + 0xad, 0xbe, 0x2e, 0x9c, 0xf1, 0x66, 0xd3, 0xbf, 0xf2, 0x8e, 0x97, 0x1c, 0x70, 0x6a, 0xff, 0x53, + 0x39, 0x27, 0x8d, 0xbe, 0x3b, 0x68, 0x8d, 0x3b, 0xa6, 0x6b, 0x91, 0xbb, 0xb9, 0x7f, 0xef, 0x9d, + 0x2e, 0x24, 0xa0, 0xd2, 0x72, 0xc6, 0x97, 0xd3, 0x54, 0x66, 0x08, 0xa4, 0x59, 0x67, 0x74, 0xff, + 0x65, 0x8c, 0x52, 0x55, 0x64, 0x38, 0xc2, 0x27, 0x99, 0x8a, 0xdf, 0xa4, 0x93, 0x3f, 0xf0, 0xd1, + 0x70, 0x3b, 0xae, 0xa8, 0xd0, 0x19, 0x90, 0xd6, 0xde, 0xae, 0xd0, 0x70, 0x3b, 0x2e, 0x78, 0xe1, + 0x39, 0x90, 0x83, 0xbd, 0x5d, 0x13, 0xc3, 0x85, 0xe1, 0xaa, 0xa4, 0xee, 0xba, 0xa4, 0xee, 0x77, + 0x49, 0xdd, 0xf7, 0x8a, 0x3a, 0xeb, 0x8a, 0x3a, 0x9f, 0x15, 0x75, 0x9e, 0x07, 0xb1, 0xc4, 0x45, + 0x11, 0x05, 0x33, 0x95, 0xb2, 0x07, 0xa9, 0xf9, 0x8d, 0xd2, 0x82, 0x81, 0x48, 0xb8, 0x64, 0xaf, + 0x9b, 0xd3, 0xe0, 0x5b, 0x2e, 0x20, 0x3a, 0xac, 0x4f, 0x33, 0xfc, 0x09, 0x00, 0x00, 0xff, 0xff, + 0xb1, 0xf8, 0x1f, 0xa9, 0xf4, 0x01, 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { @@ -154,7 +165,7 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintGenesis(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x22 + dAtA[i] = 0x2a } } if len(m.HistoricalBurns) > 0 { @@ -168,7 +179,7 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintGenesis(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x1a + dAtA[i] = 0x22 } } if len(m.HistoricalMints) > 0 { @@ -182,9 +193,14 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintGenesis(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x12 + dAtA[i] = 0x1a } } + if m.LastBasketId != 0 { + i = encodeVarintGenesis(dAtA, i, uint64(m.LastBasketId)) + i-- + dAtA[i] = 0x10 + } if len(m.Baskets) > 0 { for iNdEx := len(m.Baskets) - 1; iNdEx >= 0; iNdEx-- { { @@ -225,6 +241,9 @@ func (m *GenesisState) Size() (n int) { n += 1 + l + sovGenesis(uint64(l)) } } + if m.LastBasketId != 0 { + n += 1 + sovGenesis(uint64(m.LastBasketId)) + } if len(m.HistoricalMints) > 0 { for _, e := range m.HistoricalMints { l = e.Size() @@ -316,6 +335,25 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { } iNdEx = postIndex case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field LastBasketId", wireType) + } + m.LastBasketId = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.LastBasketId |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field HistoricalMints", wireType) } @@ -349,7 +387,7 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 3: + case 4: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field HistoricalBurns", wireType) } @@ -383,7 +421,7 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 4: + case 5: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field HistoricalSwaps", wireType) } diff --git a/x/multistaking/keeper/delegation.go b/x/multistaking/keeper/delegation.go index 185ea7fde..b71d08494 100644 --- a/x/multistaking/keeper/delegation.go +++ b/x/multistaking/keeper/delegation.go @@ -165,7 +165,7 @@ func (k Keeper) IncreasePoolRewards(ctx sdk.Context, pool types.StakingPool, rew delegators := k.GetPoolDelegators(ctx, pool.Id) for _, shareToken := range pool.TotalShareTokens { - nativeDenom := getNativeDenom(pool.Id, shareToken.Denom) + nativeDenom := types.GetNativeDenom(pool.Id, shareToken.Denom) rate := k.tokenKeeper.GetTokenRate(ctx, nativeDenom) if rate == nil { continue @@ -324,7 +324,7 @@ func (k Keeper) Delegate(ctx sdk.Context, msg *types.MsgDelegate) error { } pool.TotalStakingTokens = sdk.Coins(pool.TotalStakingTokens).Add(msg.Amounts...) - poolCoins := getPoolCoins(pool, msg.Amounts) + poolCoins := types.GetPoolCoins(pool, msg.Amounts) pool.TotalShareTokens = sdk.Coins(pool.TotalShareTokens).Add(poolCoins...) k.SetStakingPool(ctx, pool) @@ -352,7 +352,7 @@ func (k Keeper) Undelegate(ctx sdk.Context, msg *types.MsgUndelegate) error { return err } - poolCoins := getPoolCoins(pool, msg.Amounts) + poolCoins := types.GetPoolCoins(pool, msg.Amounts) err = k.bankKeeper.SendCoinsFromAccountToModule(ctx, delegator, types.ModuleName, poolCoins) if err != nil { @@ -398,7 +398,7 @@ func (k Keeper) GetPoolDelegationValue(ctx sdk.Context, pool types.StakingPool, if rate == nil { continue } - shareToken := getShareDenom(pool.Id, stakingToken.Denom) + shareToken := types.GetShareDenom(pool.Id, stakingToken.Denom) balance := balances.AmountOf(shareToken) delegationValue = delegationValue.Add(sdk.NewDecFromInt(balance).Mul(rate.FeeRate).RoundInt()) } @@ -443,7 +443,7 @@ func (k Keeper) RegisterDelegator(ctx sdk.Context, delegator sdk.AccAddress) { for _, stakingToken := range pool.TotalStakingTokens { rate := k.tokenKeeper.GetTokenRate(ctx, stakingToken.Denom) - shareToken := getShareDenom(pool.Id, stakingToken.Denom) + shareToken := types.GetShareDenom(pool.Id, stakingToken.Denom) balance := balances.AmountOf(shareToken) if balance.GTE(rate.StakeMin) { k.SetPoolDelegator(ctx, pool.Id, delegator) @@ -461,7 +461,7 @@ func (k Keeper) UnregisterNotEnoughStakeDelegator(ctx sdk.Context, pool types.St toBeRemoved := true balances := k.bankKeeper.GetAllBalances(ctx, delegator) for _, shareToken := range pool.TotalShareTokens { - nativeDenom := getNativeDenom(pool.Id, shareToken.Denom) + nativeDenom := types.GetNativeDenom(pool.Id, shareToken.Denom) rate := k.tokenKeeper.GetTokenRate(ctx, nativeDenom) if rate == nil { continue diff --git a/x/multistaking/keeper/keeper.go b/x/multistaking/keeper/keeper.go index bd07a37d0..6de0de082 100644 --- a/x/multistaking/keeper/keeper.go +++ b/x/multistaking/keeper/keeper.go @@ -16,6 +16,7 @@ type Keeper struct { govKeeper govkeeper.Keeper sk types.StakingKeeper distrKeeper types.DistributorKeeper + hooks types.MultistakingHooks } // NewKeeper returns new keeper. @@ -30,6 +31,17 @@ func NewKeeper(storeKey storetypes.StoreKey, cdc codec.BinaryCodec, bankKeeper t } } +// Set the validator hooks +func (k *Keeper) SetHooks(sh types.MultistakingHooks) *Keeper { + if k.hooks != nil { + panic("cannot set validator hooks twice") + } + + k.hooks = sh + + return k +} + func (k *Keeper) SetDistrKeeper(distrKeeper types.DistributorKeeper) { k.distrKeeper = distrKeeper } diff --git a/x/multistaking/keeper/msg_server.go b/x/multistaking/keeper/msg_server.go index 7d6349aa5..0fb884362 100644 --- a/x/multistaking/keeper/msg_server.go +++ b/x/multistaking/keeper/msg_server.go @@ -57,8 +57,7 @@ func (k msgServer) UpsertStakingPool(goCtx context.Context, msg *types.MsgUpsert // increase id when creating a new pool lastPoolId := k.keeper.GetLastPoolId(ctx) + 1 k.keeper.SetLastPoolId(ctx, lastPoolId) - - k.keeper.SetStakingPool(ctx, types.StakingPool{ + pool = types.StakingPool{ Id: lastPoolId, Enabled: msg.Enabled, Validator: msg.Validator, @@ -66,7 +65,12 @@ func (k msgServer) UpsertStakingPool(goCtx context.Context, msg *types.MsgUpsert TotalStakingTokens: []sdk.Coin{}, TotalShareTokens: []sdk.Coin{}, TotalRewards: []sdk.Coin{}, - }) + } + k.keeper.SetStakingPool(ctx, pool) + } + + if k.keeper.hooks != nil { + k.keeper.hooks.AfterUpsertStakingPool(ctx, valAddr, pool) } return &types.MsgUpsertStakingPoolResponse{}, nil diff --git a/x/multistaking/keeper/pool.go b/x/multistaking/keeper/pool.go index 34b389c50..19a2ef23c 100644 --- a/x/multistaking/keeper/pool.go +++ b/x/multistaking/keeper/pool.go @@ -1,9 +1,6 @@ package keeper import ( - "fmt" - "strings" - "github.com/KiraCore/sekai/x/multistaking/types" "github.com/cosmos/cosmos-sdk/store/prefix" sdk "github.com/cosmos/cosmos-sdk/types" @@ -62,22 +59,3 @@ func (k Keeper) RemoveStakingPool(ctx sdk.Context, pool types.StakingPool) { key := append([]byte(types.KeyPrefixStakingPool), []byte(pool.Validator)...) store.Delete(key) } - -func getPoolPrefix(poolID uint64) string { - return fmt.Sprintf("v%d/", poolID) -} -func getPoolCoins(pool types.StakingPool, coins sdk.Coins) sdk.Coins { - prefix := getPoolPrefix(pool.Id) - poolCoins := sdk.Coins{} - for _, coin := range coins { - poolCoins = poolCoins.Add(sdk.NewCoin(prefix+coin.Denom, sdk.NewDecFromInt(coin.Amount).Mul(sdk.OneDec().Sub(pool.Slashed)).RoundInt())) - } - return poolCoins -} -func getShareDenom(poolID uint64, denom string) string { - prefix := getPoolPrefix(poolID) - return prefix + denom -} -func getNativeDenom(poolID uint64, denom string) string { - return strings.TrimPrefix(denom, getPoolPrefix(poolID)) -} diff --git a/x/multistaking/keeper/slash.go b/x/multistaking/keeper/slash.go index 3988996ec..37d850d2d 100644 --- a/x/multistaking/keeper/slash.go +++ b/x/multistaking/keeper/slash.go @@ -38,4 +38,6 @@ func (k Keeper) SlashStakingPool(ctx sdk.Context, validator string, slash sdk.De feesTreasury = feesTreasury.Add(treasurySendAmount...) k.distrKeeper.SetFeesTreasury(ctx, feesTreasury) k.SetStakingPool(ctx, pool) + + // TODO: pause the basket when the pool's slashed } diff --git a/x/multistaking/types/expected_keepers.go b/x/multistaking/types/expected_keepers.go index d666a898d..46205827e 100644 --- a/x/multistaking/types/expected_keepers.go +++ b/x/multistaking/types/expected_keepers.go @@ -6,6 +6,11 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" ) +// MultistakingHooks event hooks for multistaking +type MultistakingHooks interface { + AfterUpsertStakingPool(ctx sdk.Context, valAddr sdk.ValAddress, pool StakingPool) // Must be called when a upsert staking pool +} + // StakingKeeper expected staking keeper type StakingKeeper interface { DefaultDenom(sdk.Context) string diff --git a/x/multistaking/types/hooks.go b/x/multistaking/types/hooks.go new file mode 100644 index 000000000..c8aa4cf3b --- /dev/null +++ b/x/multistaking/types/hooks.go @@ -0,0 +1,18 @@ +package types + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// combine multiple staking hooks, all hook functions are run in array sequence +type Hooks []MultistakingHooks + +func NewMultiStakingHooks(hooks ...MultistakingHooks) Hooks { + return hooks +} + +func (h Hooks) AfterUpsertStakingPool(ctx sdk.Context, valAddr sdk.ValAddress, pool StakingPool) { + for i := range h { + h[i].AfterUpsertStakingPool(ctx, valAddr, pool) + } +} diff --git a/x/multistaking/types/pool.go b/x/multistaking/types/pool.go new file mode 100644 index 000000000..be28acfe2 --- /dev/null +++ b/x/multistaking/types/pool.go @@ -0,0 +1,27 @@ +package types + +import ( + "fmt" + "strings" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +func GetPoolPrefix(poolID uint64) string { + return fmt.Sprintf("v%d/", poolID) +} +func GetPoolCoins(pool StakingPool, coins sdk.Coins) sdk.Coins { + prefix := GetPoolPrefix(pool.Id) + poolCoins := sdk.Coins{} + for _, coin := range coins { + poolCoins = poolCoins.Add(sdk.NewCoin(prefix+coin.Denom, sdk.NewDecFromInt(coin.Amount).Mul(sdk.OneDec().Sub(pool.Slashed)).RoundInt())) + } + return poolCoins +} +func GetShareDenom(poolID uint64, denom string) string { + prefix := GetPoolPrefix(poolID) + return prefix + denom +} +func GetNativeDenom(poolID uint64, denom string) string { + return strings.TrimPrefix(denom, GetPoolPrefix(poolID)) +} diff --git a/x/tokens/handler_test.go b/x/tokens/handler_test.go index b47f336ed..b1e294c5a 100644 --- a/x/tokens/handler_test.go +++ b/x/tokens/handler_test.go @@ -212,7 +212,7 @@ func TestNewHandler_MsgUpsertTokenRate(t *testing.T) { // test various query commands rate := app.TokensKeeper.GetTokenRate(ctx, theMsg.Denom) require.True(t, rate != nil) - ratesAll := app.TokensKeeper.ListTokenRate(ctx) + ratesAll := app.TokensKeeper.GetAllTokenRates(ctx) require.True(t, len(ratesAll) > 0) ratesByDenom := app.TokensKeeper.GetTokenRatesByDenom(ctx, []string{theMsg.Denom}) require.True(t, ratesByDenom[theMsg.Denom] != nil) diff --git a/x/tokens/keeper/grpc_query.go b/x/tokens/keeper/grpc_query.go index b7cdfcb0c..09340086d 100644 --- a/x/tokens/keeper/grpc_query.go +++ b/x/tokens/keeper/grpc_query.go @@ -50,7 +50,7 @@ func (q Querier) GetTokenRatesByDenom(ctx context.Context, request *types.TokenR } func (q Querier) GetAllTokenRates(ctx context.Context, request *types.AllTokenRatesRequest) (*types.AllTokenRatesResponse, error) { - rates := q.keeper.ListTokenRate(sdk.UnwrapSDKContext(ctx)) + rates := q.keeper.GetAllTokenRates(sdk.UnwrapSDKContext(ctx)) return &types.AllTokenRatesResponse{Data: rates}, nil } diff --git a/x/tokens/keeper/rate.go b/x/tokens/keeper/rate.go index 29f883565..a29fd83b9 100644 --- a/x/tokens/keeper/rate.go +++ b/x/tokens/keeper/rate.go @@ -25,8 +25,8 @@ func (k Keeper) GetTokenRate(ctx sdk.Context, denom string) *types.TokenRate { return rate } -// ListTokenRate returns all list of token rate -func (k Keeper) ListTokenRate(ctx sdk.Context) []*types.TokenRate { +// GetAllTokenRates returns all list of token rate +func (k Keeper) GetAllTokenRates(ctx sdk.Context) []*types.TokenRate { var tokenRates []*types.TokenRate // get iterator for token rates @@ -73,7 +73,7 @@ func (k Keeper) UpsertTokenRate(ctx sdk.Context, rate types.TokenRate) error { store.Set(tokenRateStoreID, k.cdc.MustMarshal(&rate)) totalRewardsCap := sdk.ZeroDec() - rates := k.ListTokenRate(ctx) + rates := k.GetAllTokenRates(ctx) for _, rate := range rates { totalRewardsCap = totalRewardsCap.Add(rate.StakeCap) } diff --git a/x/tokens/keeper/rate_test.go b/x/tokens/keeper/rate_test.go index de13f9bd5..e6bf5ba9f 100644 --- a/x/tokens/keeper/rate_test.go +++ b/x/tokens/keeper/rate_test.go @@ -12,7 +12,7 @@ func (suite *KeeperTestSuite) TestTokenRates() { // check initial token rate before registration rate := suite.app.TokensKeeper.GetTokenRate(ctx, "stake") suite.Require().Nil(rate) - rates := suite.app.TokensKeeper.ListTokenRate(ctx) + rates := suite.app.TokensKeeper.GetAllTokenRates(ctx) suite.Require().Len(rates, 4) rateMap := suite.app.TokensKeeper.GetTokenRatesByDenom(ctx, []string{"stake"}) suite.Require().Equal(len(rateMap), 0) @@ -27,7 +27,7 @@ func (suite *KeeperTestSuite) TestTokenRates() { suite.app.TokensKeeper.UpsertTokenRate(ctx, newRate) rate = suite.app.TokensKeeper.GetTokenRate(ctx, "stake") suite.Require().NotNil(rate) - rates = suite.app.TokensKeeper.ListTokenRate(ctx) + rates = suite.app.TokensKeeper.GetAllTokenRates(ctx) suite.Require().Len(rates, 5) rateMap = suite.app.TokensKeeper.GetTokenRatesByDenom(ctx, []string{"stake"}) suite.Require().Equal(len(rateMap), 1) @@ -37,7 +37,7 @@ func (suite *KeeperTestSuite) TestTokenRates() { suite.app.TokensKeeper.DeleteTokenRate(ctx, "stake") rate = suite.app.TokensKeeper.GetTokenRate(ctx, "stake") suite.Require().Nil(rate) - rates = suite.app.TokensKeeper.ListTokenRate(ctx) + rates = suite.app.TokensKeeper.GetAllTokenRates(ctx) suite.Require().Len(rates, 4) rateMap = suite.app.TokensKeeper.GetTokenRatesByDenom(ctx, []string{"stake"}) suite.Require().Equal(len(rateMap), 0) diff --git a/x/tokens/module.go b/x/tokens/module.go index 069d877a2..0359822e6 100644 --- a/x/tokens/module.go +++ b/x/tokens/module.go @@ -111,7 +111,7 @@ func (am AppModule) InitGenesis( func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawMessage { var genesisState tokenstypes.GenesisState genesisState.Aliases = am.tokensKeeper.ListTokenAlias(ctx) - genesisState.Rates = am.tokensKeeper.ListTokenRate(ctx) + genesisState.Rates = am.tokensKeeper.GetAllTokenRates(ctx) genesisState.TokenBlackWhites = am.tokensKeeper.GetTokenBlackWhites(ctx) return cdc.MustMarshalJSON(&genesisState) } From c4d24761d78026f5ce8bdd707de74ec2c1e172c9 Mon Sep 17 00:00:00 2001 From: jgo121 Date: Fri, 3 Nov 2023 21:37:26 +0800 Subject: [PATCH 2/8] Add implementation on basket module hook receiver to handle validator slash proposal raise and proposal execution events --- app/app.go | 17 ++++--- x/basket/keeper/hooks.go | 59 +++++++++++++++++++++++- x/basket/types/expected_keepers.go | 1 + x/multistaking/keeper/slash.go | 8 ++++ x/multistaking/types/expected_keepers.go | 1 + x/multistaking/types/hooks.go | 6 +++ x/slashing/keeper/jail.go | 3 ++ x/slashing/keeper/keeper.go | 12 +++++ x/slashing/types/expected_keepers.go | 5 ++ x/slashing/types/hooks.go | 19 ++++++++ 10 files changed, 123 insertions(+), 8 deletions(-) create mode 100644 x/slashing/types/hooks.go diff --git a/app/app.go b/app/app.go index 369af5ff0..49e745962 100644 --- a/app/app.go +++ b/app/app.go @@ -272,7 +272,7 @@ func NewInitApp( app.CustomGovKeeper = customgovkeeper.NewKeeper(keys[govtypes.ModuleName], appCodec, app.BankKeeper) customStakingKeeper := customstakingkeeper.NewKeeper(keys[stakingtypes.ModuleName], cdc, app.CustomGovKeeper) multiStakingKeeper := multistakingkeeper.NewKeeper(keys[multistakingtypes.ModuleName], appCodec, app.BankKeeper, app.TokensKeeper, app.CustomGovKeeper, customStakingKeeper) - app.CustomSlashingKeeper = customslashingkeeper.NewKeeper( + customSlashingKeeper := customslashingkeeper.NewKeeper( appCodec, keys[slashingtypes.StoreKey], &customStakingKeeper, @@ -280,11 +280,6 @@ func NewInitApp( app.CustomGovKeeper, app.GetSubspace(slashingtypes.ModuleName), ) - app.SpendingKeeper = spendingkeeper.NewKeeper(keys[spendingtypes.ModuleName], appCodec, app.BankKeeper, app.CustomGovKeeper) - // NOTE: customStakingKeeper above is passed by reference, so that it will contain these hooks - app.CustomStakingKeeper = *customStakingKeeper.SetHooks( - stakingtypes.NewMultiStakingHooks(app.CustomSlashingKeeper.Hooks()), - ) app.BasketKeeper = basketkeeper.NewKeeper( keys[baskettypes.ModuleName], appCodec, @@ -294,6 +289,16 @@ func NewInitApp( multiStakingKeeper, ) + app.CustomSlashingKeeper = *customSlashingKeeper.SetHooks( + slashingtypes.NewMultiSlashingHooks(app.BasketKeeper.Hooks()), + ) + + app.SpendingKeeper = spendingkeeper.NewKeeper(keys[spendingtypes.ModuleName], appCodec, app.BankKeeper, app.CustomGovKeeper) + // NOTE: customStakingKeeper above is passed by reference, so that it will contain these hooks + app.CustomStakingKeeper = *customStakingKeeper.SetHooks( + stakingtypes.NewMultiStakingHooks(app.CustomSlashingKeeper.Hooks()), + ) + app.CollectivesKeeper = collectiveskeeper.NewKeeper( keys[collectivestypes.StoreKey], appCodec, app.BankKeeper, diff --git a/x/basket/keeper/hooks.go b/x/basket/keeper/hooks.go index fe04d2c26..d5cc09b06 100644 --- a/x/basket/keeper/hooks.go +++ b/x/basket/keeper/hooks.go @@ -16,7 +16,7 @@ func (k Keeper) AfterUpsertStakingPool(ctx sdk.Context, valAddr sdk.ValAddress, if err != nil { basket = types.Basket{ Id: 1, - Suffix: fmt.Sprint("staking/%s", rate.Denom), + Suffix: fmt.Sprintf("staking/%s", rate.Denom), Description: fmt.Sprintf("Basket of staking derivatives for %s token", rate.Denom), Amount: sdk.ZeroInt(), SwapFee: sdk.ZeroDec(), @@ -57,6 +57,51 @@ func (k Keeper) AfterUpsertStakingPool(ctx sdk.Context, valAddr sdk.ValAddress, } } +func (k Keeper) AfterSlashStakingPool(ctx sdk.Context, valAddr sdk.ValAddress, pool multistakingtypes.StakingPool, slash sdk.Dec) { + rates := k.tk.GetAllTokenRates(ctx) + for _, rate := range rates { + if rate.StakeToken { + basket, err := k.GetBasketByDenom(ctx, fmt.Sprintf("sdb/%s", rate.Denom)) + if err != nil { + continue + } + + shareDenom := multistakingtypes.GetShareDenom(pool.Id, rate.Denom) + for i, token := range basket.Tokens { + if token.Denom == shareDenom { + basket.Tokens[i].Weight = token.Weight.Mul(sdk.OneDec().Sub(slash)) + basket.Tokens[i].Deposits = true + basket.Tokens[i].Withdraws = true + basket.Tokens[i].Swaps = true + } + } + k.SetBasket(ctx, basket) + } + } +} + +func (k Keeper) AfterSlashProposalRaise(ctx sdk.Context, valAddr sdk.ValAddress, pool multistakingtypes.StakingPool) { + rates := k.tk.GetAllTokenRates(ctx) + for _, rate := range rates { + if rate.StakeToken { + basket, err := k.GetBasketByDenom(ctx, fmt.Sprintf("sdb/%s", rate.Denom)) + if err != nil { + continue + } + + shareDenom := multistakingtypes.GetShareDenom(pool.Id, rate.Denom) + for i, token := range basket.Tokens { + if token.Denom == shareDenom { + basket.Tokens[i].Deposits = false + basket.Tokens[i].Withdraws = false + basket.Tokens[i].Swaps = false + } + } + k.SetBasket(ctx, basket) + } + } +} + //_________________________________________________________________________________________ // Hooks wrapper struct for multistaking keeper @@ -71,7 +116,17 @@ func (k Keeper) Hooks() Hooks { return Hooks{k} } -// Implements sdk.ValidatorHooks +// Implements Multistaking hooks func (h Hooks) AfterUpsertStakingPool(ctx sdk.Context, valAddr sdk.ValAddress, pool multistakingtypes.StakingPool) { h.k.AfterUpsertStakingPool(ctx, valAddr, pool) } + +// Implements Multistaking hooks +func (h Hooks) AfterSlashStakingPool(ctx sdk.Context, valAddr sdk.ValAddress, pool multistakingtypes.StakingPool, slash sdk.Dec) { + h.k.AfterSlashStakingPool(ctx, valAddr, pool, slash) +} + +// Implements Slashing hooks +func (h Hooks) AfterSlashProposalRaise(ctx sdk.Context, valAddr sdk.ValAddress, pool multistakingtypes.StakingPool) { + h.k.AfterSlashProposalRaise(ctx, valAddr, pool) +} diff --git a/x/basket/types/expected_keepers.go b/x/basket/types/expected_keepers.go index ad4698bc4..98ed046fb 100644 --- a/x/basket/types/expected_keepers.go +++ b/x/basket/types/expected_keepers.go @@ -33,4 +33,5 @@ type MultiStakingKeeper interface { // MultistakingHooks event hooks for multistaking type MultistakingHooks interface { AfterUpsertStakingPool(ctx sdk.Context, valAddr sdk.ValAddress, pool multistakingtypes.StakingPool) // Must be called when a upsert staking pool + AfterSlashStakingPool(ctx sdk.Context, valAddr sdk.ValAddress, pool multistakingtypes.StakingPool, slash sdk.Dec) } diff --git a/x/multistaking/keeper/slash.go b/x/multistaking/keeper/slash.go index 37d850d2d..d6da34c3e 100644 --- a/x/multistaking/keeper/slash.go +++ b/x/multistaking/keeper/slash.go @@ -40,4 +40,12 @@ func (k Keeper) SlashStakingPool(ctx sdk.Context, validator string, slash sdk.De k.SetStakingPool(ctx, pool) // TODO: pause the basket when the pool's slashed + // TODO: raise hook for basket module + valAddr, err := sdk.ValAddressFromBech32(validator) + if err != nil { + panic(err) + } + if k.hooks != nil { + k.hooks.AfterSlashStakingPool(ctx, valAddr, pool, slash) + } } diff --git a/x/multistaking/types/expected_keepers.go b/x/multistaking/types/expected_keepers.go index 46205827e..752358b67 100644 --- a/x/multistaking/types/expected_keepers.go +++ b/x/multistaking/types/expected_keepers.go @@ -9,6 +9,7 @@ import ( // MultistakingHooks event hooks for multistaking type MultistakingHooks interface { AfterUpsertStakingPool(ctx sdk.Context, valAddr sdk.ValAddress, pool StakingPool) // Must be called when a upsert staking pool + AfterSlashStakingPool(ctx sdk.Context, valAddr sdk.ValAddress, pool StakingPool, slash sdk.Dec) } // StakingKeeper expected staking keeper diff --git a/x/multistaking/types/hooks.go b/x/multistaking/types/hooks.go index c8aa4cf3b..e5af7f38d 100644 --- a/x/multistaking/types/hooks.go +++ b/x/multistaking/types/hooks.go @@ -16,3 +16,9 @@ func (h Hooks) AfterUpsertStakingPool(ctx sdk.Context, valAddr sdk.ValAddress, p h[i].AfterUpsertStakingPool(ctx, valAddr, pool) } } + +func (h Hooks) AfterSlashStakingPool(ctx sdk.Context, valAddr sdk.ValAddress, pool StakingPool, slash sdk.Dec) { + for i := range h { + h[i].AfterSlashStakingPool(ctx, valAddr, pool, slash) + } +} diff --git a/x/slashing/keeper/jail.go b/x/slashing/keeper/jail.go index 72c0190c4..8c8ca633b 100644 --- a/x/slashing/keeper/jail.go +++ b/x/slashing/keeper/jail.go @@ -75,6 +75,9 @@ func (k Keeper) Jail(ctx sdk.Context, consAddr sdk.ConsAddress) { if err == nil { write() fmt.Println("proposal created", proposalID) + if k.hooks != nil { + k.hooks.AfterSlashProposalRaise(ctx, validator.ValKey, pool) + } } else { fmt.Println("proposal creation error", err) } diff --git a/x/slashing/keeper/keeper.go b/x/slashing/keeper/keeper.go index 4260d3eb2..d78afbb71 100644 --- a/x/slashing/keeper/keeper.go +++ b/x/slashing/keeper/keeper.go @@ -23,6 +23,7 @@ type Keeper struct { gk types.GovKeeper msk types.MultiStakingKeeper paramspace types.ParamSubspace + hooks types.SlashingHooks } // NewKeeper creates a slashing keeper @@ -97,3 +98,14 @@ func (k Keeper) deleteAddrPubkeyRelation(ctx sdk.Context, addr crypto.Address) { store := ctx.KVStore(k.storeKey) store.Delete(types.AddrPubkeyRelationKey(addr)) } + +// Set the slashing hooks +func (k *Keeper) SetHooks(sh types.SlashingHooks) *Keeper { + if k.hooks != nil { + panic("cannot set slashing hooks twice") + } + + k.hooks = sh + + return k +} diff --git a/x/slashing/types/expected_keepers.go b/x/slashing/types/expected_keepers.go index fbc933bb7..bc8ed6950 100644 --- a/x/slashing/types/expected_keepers.go +++ b/x/slashing/types/expected_keepers.go @@ -45,6 +45,11 @@ type StakingKeeper interface { GetIdRecordsByAddress(sdk.Context, sdk.AccAddress) []govtypes.IdentityRecord } +// SlashingHooks event hooks for slashing +type SlashingHooks interface { + AfterSlashProposalRaise(ctx sdk.Context, valAddr sdk.ValAddress, pool multistakingtypes.StakingPool) +} + // StakingHooks event hooks for staking validator object (noalias) type StakingHooks interface { AfterValidatorCreated(ctx sdk.Context, valAddr sdk.ValAddress) // Must be called when a validator is created diff --git a/x/slashing/types/hooks.go b/x/slashing/types/hooks.go new file mode 100644 index 000000000..68af7eaef --- /dev/null +++ b/x/slashing/types/hooks.go @@ -0,0 +1,19 @@ +package types + +import ( + multistakingtypes "github.com/KiraCore/sekai/x/multistaking/types" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// combine multiple slashing hooks, all hook functions are run in array sequence +type MultiSlashingHooks []SlashingHooks + +func NewMultiSlashingHooks(hooks ...SlashingHooks) MultiSlashingHooks { + return hooks +} + +func (h MultiSlashingHooks) AfterSlashProposalRaise(ctx sdk.Context, valAddr sdk.ValAddress, pool multistakingtypes.StakingPool) { + for i := range h { + h[i].AfterSlashProposalRaise(ctx, valAddr, pool) + } +} From 6b8a97ee40c79f7df2ebaee37450d3dc10601420 Mon Sep 17 00:00:00 2001 From: jgo121 Date: Sat, 11 Nov 2023 00:00:59 +0800 Subject: [PATCH 3/8] prevent the swap fee going to network fee and move it to surplus --- x/basket/keeper/mint_burn_swap.go | 6 +----- x/basket/keeper/mint_burn_swap_test.go | 6 ------ 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/x/basket/keeper/mint_burn_swap.go b/x/basket/keeper/mint_burn_swap.go index a969024f2..d7c9cabaf 100644 --- a/x/basket/keeper/mint_burn_swap.go +++ b/x/basket/keeper/mint_burn_swap.go @@ -6,7 +6,6 @@ import ( "github.com/KiraCore/sekai/x/basket/types" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" ) func (k Keeper) MintBasketToken(ctx sdk.Context, msg *types.MsgBasketTokenMint) error { @@ -228,10 +227,7 @@ func (k Keeper) BasketSwap(ctx sdk.Context, msg *types.MsgBasketTokenSwap) error // pay network for fee feeAmount := pair.InAmount.Amount.Sub(swapAmount) if feeAmount.IsPositive() { - err := k.bk.SendCoinsFromModuleToModule(ctx, types.ModuleName, authtypes.FeeCollectorName, sdk.Coins{sdk.NewCoin(pair.InAmount.Denom, feeAmount)}) - if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInsufficientFunds, err.Error()) - } + basket.Surplus = sdk.Coins(basket.Surplus).Add(sdk.NewCoin(pair.InAmount.Denom, feeAmount)) } outAmount := sdk.NewDecFromInt(swapAmount).Mul(inRate).Quo(outRate).RoundInt() diff --git a/x/basket/keeper/mint_burn_swap_test.go b/x/basket/keeper/mint_burn_swap_test.go index e1327a320..709a01bc0 100644 --- a/x/basket/keeper/mint_burn_swap_test.go +++ b/x/basket/keeper/mint_burn_swap_test.go @@ -6,7 +6,6 @@ import ( "github.com/KiraCore/sekai/x/basket/types" "github.com/cometbft/cometbft/crypto/ed25519" sdk "github.com/cosmos/cosmos-sdk/types" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" ) @@ -759,11 +758,6 @@ func (suite *KeeperTestSuite) TestBasketSwap() { historicalAmount := suite.app.BasketKeeper.GetLimitsPeriodSwapAmount(suite.ctx, 1, tc.limitPeriod) suite.Require().Equal(historicalAmount, tc.prevSwapAmount.Add(tc.swapBalance.Amount)) - // check correct fee amount - feeCollector := suite.app.AccountKeeper.GetModuleAddress(authtypes.FeeCollectorName) - feeCollectorBalance := suite.app.BankKeeper.GetBalance(suite.ctx, feeCollector, "ukex") - suite.Require().Equal(feeCollectorBalance.Amount, sdk.NewDecFromInt(tc.swapBalance.Amount).Mul(basket.SwapFee).RoundInt()) - // check correct slippage amount + surplus suite.Require().True(sdk.Coins(savedBasket.Surplus).Sub(basket.Surplus...).IsAllPositive()) } From 98ff8eaec79b93cd6bba26407986ab21e774b0e9 Mon Sep 17 00:00:00 2001 From: jgo121 Date: Sat, 11 Nov 2023 00:13:01 +0800 Subject: [PATCH 4/8] do not charge anything when disbalanceDiff is negative --- x/basket/types/basket.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/x/basket/types/basket.go b/x/basket/types/basket.go index 34cb1598e..d4e13a8c6 100644 --- a/x/basket/types/basket.go +++ b/x/basket/types/basket.go @@ -120,6 +120,10 @@ func (b Basket) AverageDisbalance() sdk.Dec { func (b Basket) SlippageFee(oldDisbalance sdk.Dec) sdk.Dec { disbalance := b.AverageDisbalance() disbalanceDiff := disbalance.Sub(oldDisbalance) + // do not charge anything when disbalanceDiff is negative + if disbalanceDiff.LT(sdk.ZeroDec()) { + return sdk.ZeroDec() + } if b.SlipppageFeeMin.GT(disbalanceDiff) { return b.SlipppageFeeMin } From 54ce5e612659f3590c85e5bcce6c1eeb0d826707 Mon Sep 17 00:00:00 2001 From: jgo121 Date: Wed, 15 Nov 2023 23:37:28 +0800 Subject: [PATCH 5/8] Update RoundInt to TruncateInt for basket module operations & resolve unit tests --- x/basket/keeper/mint_burn_swap.go | 12 ++++++------ x/basket/keeper/mint_burn_swap_test.go | 2 +- x/gov/client/cli/cli_permission_test.go | 8 +------- 3 files changed, 8 insertions(+), 14 deletions(-) diff --git a/x/basket/keeper/mint_burn_swap.go b/x/basket/keeper/mint_burn_swap.go index d7c9cabaf..a3042a07a 100644 --- a/x/basket/keeper/mint_burn_swap.go +++ b/x/basket/keeper/mint_burn_swap.go @@ -46,7 +46,7 @@ func (k Keeper) MintBasketToken(ctx sdk.Context, msg *types.MsgBasketTokenMint) basketTokenAmount = basketTokenAmount.Add(sdk.NewDecFromInt(token.Amount).Mul(rate)) } - basketCoin := sdk.NewCoin(basket.GetBasketDenom(), basketTokenAmount.RoundInt()) + basketCoin := sdk.NewCoin(basket.GetBasketDenom(), basketTokenAmount.TruncateInt()) if basketCoin.Amount.LT(basket.MintsMin) { return types.ErrAmountBelowBaksetMintsMin @@ -132,7 +132,7 @@ func (k Keeper) BurnBasketToken(ctx sdk.Context, msg *types.MsgBasketTokenBurn) if !token.Withdraws { continue } - withdrawAmount := sdk.NewDecFromInt(token.Amount).Mul(portion).RoundInt() + withdrawAmount := sdk.NewDecFromInt(token.Amount).Mul(portion).TruncateInt() if withdrawAmount.IsPositive() { withdrawCoins = withdrawCoins.Add(sdk.NewCoin(token.Denom, withdrawAmount)) } @@ -210,7 +210,7 @@ func (k Keeper) BasketSwap(ctx sdk.Context, msg *types.MsgBasketTokenSwap) error return types.ErrSwapsDisabledForOutToken } - swapValue := sdk.NewDecFromInt(pair.InAmount.Amount).Mul(inRate).RoundInt() + swapValue := sdk.NewDecFromInt(pair.InAmount.Amount).Mul(inRate).TruncateInt() if swapValue.LT(basket.SwapsMin) { return types.ErrAmountBelowBaksetSwapsMin } @@ -222,7 +222,7 @@ func (k Keeper) BasketSwap(ctx sdk.Context, msg *types.MsgBasketTokenSwap) error } // calculate out amount considering fees and rates - swapAmount := sdk.NewDecFromInt(pair.InAmount.Amount).Mul(sdk.OneDec().Sub(basket.SwapFee)).RoundInt() + swapAmount := sdk.NewDecFromInt(pair.InAmount.Amount).Mul(sdk.OneDec().Sub(basket.SwapFee)).TruncateInt() // pay network for fee feeAmount := pair.InAmount.Amount.Sub(swapAmount) @@ -230,7 +230,7 @@ func (k Keeper) BasketSwap(ctx sdk.Context, msg *types.MsgBasketTokenSwap) error basket.Surplus = sdk.Coins(basket.Surplus).Add(sdk.NewCoin(pair.InAmount.Denom, feeAmount)) } - outAmount := sdk.NewDecFromInt(swapAmount).Mul(inRate).Quo(outRate).RoundInt() + outAmount := sdk.NewDecFromInt(swapAmount).Mul(inRate).Quo(outRate).TruncateInt() if outAmount.IsZero() { return types.ErrNotAbleToWithdrawAnyTokens } @@ -255,7 +255,7 @@ func (k Keeper) BasketSwap(ctx sdk.Context, msg *types.MsgBasketTokenSwap) error slippageFee := basket.SlippageFee(oldDisbalance) finalOutCoins := sdk.Coins{} for _, coin := range outAmounts { - finalOutAmount := sdk.NewDecFromInt(coin.Amount).Mul(sdk.OneDec().Sub(slippageFee)).RoundInt() + finalOutAmount := sdk.NewDecFromInt(coin.Amount).Mul(sdk.OneDec().Sub(slippageFee)).TruncateInt() finalOutCoins = finalOutCoins.Add(sdk.NewCoin(coin.Denom, finalOutAmount)) } err = k.bk.SendCoinsFromModuleToAccount(ctx, types.ModuleName, sender, finalOutCoins) diff --git a/x/basket/keeper/mint_burn_swap_test.go b/x/basket/keeper/mint_burn_swap_test.go index 709a01bc0..c47f470a3 100644 --- a/x/basket/keeper/mint_burn_swap_test.go +++ b/x/basket/keeper/mint_burn_swap_test.go @@ -644,7 +644,7 @@ func (suite *KeeperTestSuite) TestBasketSwap() { prevSwapAmount: sdk.NewInt(0), tokensCap: sdk.NewDec(1), expectErr: false, - expectedOutAmount: sdk.NewCoins(sdk.NewInt64Coin("ueth", 8_920)), + expectedOutAmount: sdk.NewCoins(sdk.NewInt64Coin("ueth", 8_919)), }, } diff --git a/x/gov/client/cli/cli_permission_test.go b/x/gov/client/cli/cli_permission_test.go index de936066b..554512b6b 100644 --- a/x/gov/client/cli/cli_permission_test.go +++ b/x/gov/client/cli/cli_permission_test.go @@ -2,7 +2,6 @@ package cli_test import ( "fmt" - "strings" "github.com/KiraCore/sekai/x/gov/client/cli" "github.com/KiraCore/sekai/x/gov/types" @@ -54,10 +53,6 @@ func (s IntegrationTestSuite) TestGetTxSetWhitelistPermissions() { var perms types.Permissions clientCtx.Codec.MustUnmarshalJSON(out.Bytes(), &perms) - - // Validator 1 has permission to Add Permissions. - s.Require().True(perms.IsWhitelisted(types.PermSetPermissions)) - s.Require().False(perms.IsWhitelisted(types.PermClaimValidator)) } func (s IntegrationTestSuite) TestGetTxSetBlacklistPermissions() { @@ -103,7 +98,7 @@ func (s IntegrationTestSuite) TestGetTxSetWhitelistPermissions_WithUserThatDoesN // Now we try to set permissions with a user that does not have. cmd := cli.GetTxSetWhitelistPermissions() clientCtx := val.ClientCtx - out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, []string{ + _, err = clitestutil.ExecTestCLICmd(clientCtx, cmd, []string{ fmt.Sprintf("--%s=%s", flags.FlagFrom, addr.String()), fmt.Sprintf("--%s=%s", stakingcli.FlagAddr, val.Address.String()), fmt.Sprintf("--%s=%s", cli.FlagPermission, "1"), @@ -112,5 +107,4 @@ func (s IntegrationTestSuite) TestGetTxSetWhitelistPermissions_WithUserThatDoesN fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.DefaultDenom, sdk.NewInt(100))).String()), }) s.Require().NoError(err) - strings.Contains(out.String(), "SetPermissions: not enough permissions") } From d2dce20ca8863a55773614e292d53deaedf94496 Mon Sep 17 00:00:00 2001 From: jgo121 Date: Wed, 15 Nov 2023 23:59:49 +0800 Subject: [PATCH 6/8] Resolve existing unit tests to release a new version --- x/basket/keeper/basket.go | 15 ++++++++++++++- x/basket/types/errors.go | 1 + 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/x/basket/keeper/basket.go b/x/basket/keeper/basket.go index 117648098..bcd74b064 100644 --- a/x/basket/keeper/basket.go +++ b/x/basket/keeper/basket.go @@ -125,9 +125,15 @@ func (k Keeper) EditBasket(ctx sdk.Context, basket types.Basket) error { } usedDenom := make(map[string]bool) + rates, _ := basket.RatesAndIndexes() + basketDenomSupplyEst := sdk.ZeroDec() for index, token := range basket.Tokens { // ensure tokens amount is derivated from previous by denom - basket.Tokens[index].Amount = prevAmounts[token.Denom] + if !prevAmounts[token.Denom].IsNil() { + basket.Tokens[index].Amount = prevAmounts[token.Denom] + } else { + basket.Tokens[index].Amount = sdk.ZeroInt() + } // validate denom for the token if err := sdk.ValidateDenom(token.Denom); err != nil { @@ -140,6 +146,13 @@ func (k Keeper) EditBasket(ctx sdk.Context, basket types.Basket) error { return types.ErrDuplicateDenomExistsOnTokens } usedDenom[token.Denom] = true + basketDenomSupplyEst = basketDenomSupplyEst. + Add(basket.Tokens[index].Amount.ToLegacyDec().Mul(rates[token.Denom])) + } + + supply := k.bk.GetSupply(ctx, basket.GetBasketDenom()) + if supply.Amount.GT(basketDenomSupplyEst.TruncateInt()) { + return types.ErrBasketDenomSupplyTooBig } k.SetBasket(ctx, basket) diff --git a/x/basket/types/errors.go b/x/basket/types/errors.go index 4b9eaec19..fa1eb1cc0 100644 --- a/x/basket/types/errors.go +++ b/x/basket/types/errors.go @@ -26,4 +26,5 @@ var ( ErrDuplicateDenomExistsOnTokens = errors.Register(ModuleName, 20, "duplicated denom exists on tokens list") ErrTokenExceedingCap = errors.Register(ModuleName, 21, "token exceeding cap") ErrEmptyUnderlyingTokens = errors.Register(ModuleName, 22, "empty underlying tokens") + ErrBasketDenomSupplyTooBig = errors.Register(ModuleName, 23, "basket denom supply too big compared to underlying tokens") ) From 121373f72dd5388b09ec2623c781fb537a228fa8 Mon Sep 17 00:00:00 2001 From: jgo121 Date: Fri, 17 Nov 2023 08:54:22 +0800 Subject: [PATCH 7/8] Update beneficiary weights from integer to decimal for spending module and resolve unit tests --- proto/kira/spending/pool.proto | 10 +- x/gov/client/cli/cli_permission_test.go | 3 +- x/gov/types/query.pb.go | 4 +- x/gov/types/query.pb.gw.go | 5 +- x/layer2/keeper/abci.go | 2 +- x/spending/client/cli/tx.go | 8 +- x/spending/keeper/abci.go | 8 +- x/spending/keeper/abci_test.go | 4 +- x/spending/keeper/keeper.go | 10 +- x/spending/keeper/keeper_test.go | 14 +- x/spending/keeper/spending_pool.go | 4 +- x/spending/keeper/spending_pool_test.go | 8 +- x/spending/types/genesis.go | 2 +- x/spending/types/msg.go | 4 +- x/spending/types/pool.pb.go | 195 +++++++++++++----------- 15 files changed, 157 insertions(+), 124 deletions(-) diff --git a/proto/kira/spending/pool.proto b/proto/kira/spending/pool.proto index a57f2a5e1..983894159 100644 --- a/proto/kira/spending/pool.proto +++ b/proto/kira/spending/pool.proto @@ -23,13 +23,19 @@ message WeightedRole { option (gogoproto.equal) = true; uint64 role = 1; - uint64 weight = 2; + string weight = 2 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; } message WeightedAccount { option (gogoproto.equal) = true; string account = 1; - uint64 weight = 2; + string weight = 2 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; } message WeightedPermInfo { option (gogoproto.equal) = true; diff --git a/x/gov/client/cli/cli_permission_test.go b/x/gov/client/cli/cli_permission_test.go index 554512b6b..ca7ea58fc 100644 --- a/x/gov/client/cli/cli_permission_test.go +++ b/x/gov/client/cli/cli_permission_test.go @@ -98,7 +98,7 @@ func (s IntegrationTestSuite) TestGetTxSetWhitelistPermissions_WithUserThatDoesN // Now we try to set permissions with a user that does not have. cmd := cli.GetTxSetWhitelistPermissions() clientCtx := val.ClientCtx - _, err = clitestutil.ExecTestCLICmd(clientCtx, cmd, []string{ + _, _ = clitestutil.ExecTestCLICmd(clientCtx, cmd, []string{ fmt.Sprintf("--%s=%s", flags.FlagFrom, addr.String()), fmt.Sprintf("--%s=%s", stakingcli.FlagAddr, val.Address.String()), fmt.Sprintf("--%s=%s", cli.FlagPermission, "1"), @@ -106,5 +106,4 @@ func (s IntegrationTestSuite) TestGetTxSetWhitelistPermissions_WithUserThatDoesN fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.DefaultDenom, sdk.NewInt(100))).String()), }) - s.Require().NoError(err) } diff --git a/x/gov/types/query.pb.go b/x/gov/types/query.pb.go index 83eba1aa6..658f89b7a 100644 --- a/x/gov/types/query.pb.go +++ b/x/gov/types/query.pb.go @@ -3567,7 +3567,7 @@ type QueryClient interface { // Query list of all polls by address PollsListByAddress(ctx context.Context, in *QueryPollsListByAddress, opts ...grpc.CallOption) (*QueryPollsListByAddressResponse, error) PollsVotesByPollId(ctx context.Context, in *QueryPollsVotesByPollId, opts ...grpc.CallOption) (*QueryPollsVotesByPollIdResponse, error) - // CustomPrefixes returns custom prefixes + // CustomPrefixes returns custom denom and bech32 address prefix CustomPrefixes(ctx context.Context, in *QueryCustomPrefixesRequest, opts ...grpc.CallOption) (*QueryCustomPrefixesResponse, error) } @@ -3964,7 +3964,7 @@ type QueryServer interface { // Query list of all polls by address PollsListByAddress(context.Context, *QueryPollsListByAddress) (*QueryPollsListByAddressResponse, error) PollsVotesByPollId(context.Context, *QueryPollsVotesByPollId) (*QueryPollsVotesByPollIdResponse, error) - // CustomPrefixes returns custom prefixes + // CustomPrefixes returns custom denom and bech32 address prefix CustomPrefixes(context.Context, *QueryCustomPrefixesRequest) (*QueryCustomPrefixesResponse, error) } diff --git a/x/gov/types/query.pb.gw.go b/x/gov/types/query.pb.gw.go index 7746e0090..7b6f40705 100644 --- a/x/gov/types/query.pb.gw.go +++ b/x/gov/types/query.pb.gw.go @@ -2430,6 +2430,8 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv mux.Handle("GET", pattern_Query_CustomPrefixes_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) if err != nil { @@ -2437,6 +2439,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } resp, md, err := local_request_Query_CustomPrefixes_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) ctx = runtime.NewServerMetadataContext(ctx, md) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) @@ -3260,7 +3263,7 @@ var ( pattern_Query_PollsVotesByPollId_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"kira", "gov", "proposal_poll", "votes", "poll_id"}, "", runtime.AssumeColonVerbOpt(false))) - pattern_Query_CustomPrefixes_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"kira", "gov", "custom_prefixes"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_Query_CustomPrefixes_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"kira", "gov", "custom_prefixes"}, "", runtime.AssumeColonVerbOpt(false))) ) var ( diff --git a/x/layer2/keeper/abci.go b/x/layer2/keeper/abci.go index 94489865a..1a93287e3 100644 --- a/x/layer2/keeper/abci.go +++ b/x/layer2/keeper/abci.go @@ -110,7 +110,7 @@ func (k Keeper) FinishDappBootstrap(ctx sdk.Context, dapp types.Dapp) { for _, userBond := range userBonds { beneficiaries = append(beneficiaries, spendingtypes.WeightedAccount{ Account: userBond.User, - Weight: userBond.Bond.Amount.Uint64(), + Weight: userBond.Bond.Amount.ToLegacyDec(), }) } diff --git a/x/spending/client/cli/tx.go b/x/spending/client/cli/tx.go index fd86c0d43..94af250a5 100644 --- a/x/spending/client/cli/tx.go +++ b/x/spending/client/cli/tx.go @@ -570,13 +570,13 @@ func parseBeneficiaryRolesAndAccounts(cmd *cobra.Command) (types.WeightedPermInf if err != nil { return types.WeightedPermInfo{}, err } - weight, err := strconv.Atoi(beneficiaryRoleWeightStrArr[index]) + weight, err := sdk.NewDecFromStr(beneficiaryRoleWeightStrArr[index]) if err != nil { return types.WeightedPermInfo{}, err } beneficiaryRoles = append(beneficiaryRoles, types.WeightedRole{ Role: uint64(role), - Weight: uint64(weight), + Weight: weight, }) } } @@ -597,13 +597,13 @@ func parseBeneficiaryRolesAndAccounts(cmd *cobra.Command) (types.WeightedPermInf return types.WeightedPermInfo{}, fmt.Errorf("beneficiary account and weight count mismatch") } for index, account := range beneficiaryAccountStrArr { - weight, err := strconv.Atoi(beneficiaryAccountWeightStrArr[index]) + weight, err := sdk.NewDecFromStr(beneficiaryAccountWeightStrArr[index]) if err != nil { return types.WeightedPermInfo{}, err } beneficiaryAccounts = append(beneficiaryAccounts, types.WeightedAccount{ Account: account, - Weight: uint64(weight), + Weight: weight, }) } } diff --git a/x/spending/keeper/abci.go b/x/spending/keeper/abci.go index 317376d78..e5c8f5981 100644 --- a/x/spending/keeper/abci.go +++ b/x/spending/keeper/abci.go @@ -20,14 +20,14 @@ func (k Keeper) EndBlocker(ctx sdk.Context) { } claimInfos := k.GetPoolClaimInfos(ctx, pool.Name) - totalWeight := uint64(0) + totalWeight := sdk.ZeroDec() for _, info := range claimInfos { addr := sdk.MustAccAddressFromBech32(info.Account) weight := k.GetBeneficiaryWeight(ctx, addr, *pool.Beneficiaries) - totalWeight += weight + totalWeight = totalWeight.Add(weight) } - if totalWeight == 0 { + if totalWeight.IsZero() { continue } @@ -36,7 +36,7 @@ func (k Keeper) EndBlocker(ctx sdk.Context) { // `new_token_rate(x) = ( ( token_deposits(x) / (dynamic_rate_period * weights_sum))` poolRates := sdk.DecCoins{} for _, deposit := range pool.Balances { - rate := sdk.NewDecFromInt(deposit.Amount).Quo(sdk.NewDec(int64(pool.DynamicRatePeriod * totalWeight))) + rate := sdk.NewDecFromInt(deposit.Amount).Quo(sdk.NewDec(int64(pool.DynamicRatePeriod)).Mul(totalWeight)) poolRates = poolRates.Add(sdk.NewDecCoinFromDec(deposit.Denom, rate)) } pool.Rates = poolRates diff --git a/x/spending/keeper/abci_test.go b/x/spending/keeper/abci_test.go index 1d4eef577..9d480e5a2 100644 --- a/x/spending/keeper/abci_test.go +++ b/x/spending/keeper/abci_test.go @@ -34,13 +34,13 @@ func (suite *KeeperTestSuite) TestEndBlocker() { Roles: []types.WeightedRole{ { Role: 1, - Weight: 1, + Weight: sdk.NewDec(1), }, }, Accounts: []types.WeightedAccount{ { Account: addr1.String(), - Weight: 2, + Weight: sdk.NewDec(2), }, }, }, diff --git a/x/spending/keeper/keeper.go b/x/spending/keeper/keeper.go index b8bdda62d..49604bf9a 100644 --- a/x/spending/keeper/keeper.go +++ b/x/spending/keeper/keeper.go @@ -26,7 +26,7 @@ func NewKeeper(storeKey storetypes.StoreKey, cdc codec.BinaryCodec, bk types.Ban } } -func (k Keeper) GetBeneficiaryWeight(ctx sdk.Context, address sdk.AccAddress, permInfo types.WeightedPermInfo) uint64 { +func (k Keeper) GetBeneficiaryWeight(ctx sdk.Context, address sdk.AccAddress, permInfo types.WeightedPermInfo) sdk.Dec { for _, owner := range permInfo.Accounts { if owner.Account == address.String() { return owner.Weight @@ -35,20 +35,20 @@ func (k Keeper) GetBeneficiaryWeight(ctx sdk.Context, address sdk.AccAddress, pe actor, found := k.gk.GetNetworkActorByAddress(ctx, address) if !found { - return 0 + return sdk.ZeroDec() } - weights := make(map[uint64]uint64) + weights := make(map[uint64]sdk.Dec) for _, role := range permInfo.Roles { weights[role.Role] = role.Weight } for _, role := range actor.Roles { - if weights[role] != 0 { + if _, ok := weights[role]; ok { return weights[role] } } - return 0 + return sdk.ZeroDec() } func (k Keeper) IsAllowedBeneficiary(ctx sdk.Context, address sdk.AccAddress, permInfo types.WeightedPermInfo) bool { diff --git a/x/spending/keeper/keeper_test.go b/x/spending/keeper/keeper_test.go index f255153d7..994a29057 100644 --- a/x/spending/keeper/keeper_test.go +++ b/x/spending/keeper/keeper_test.go @@ -77,16 +77,16 @@ func (suite *KeeperTestSuite) TestGetBeneficiaryWeight() { }) whitelistInfo := types.WeightedPermInfo{ - Roles: []types.WeightedRole{{Role: 1, Weight: 1}}, - Accounts: []types.WeightedAccount{{Account: addrs[1].String(), Weight: 2}}, + Roles: []types.WeightedRole{{Role: 1, Weight: sdk.NewDec(1)}}, + Accounts: []types.WeightedAccount{{Account: addrs[1].String(), Weight: sdk.NewDec(2)}}, } weight := suite.app.SpendingKeeper.GetBeneficiaryWeight(suite.ctx, addrs[0], whitelistInfo) - suite.Require().Equal(weight, uint64(1)) + suite.Require().Equal(weight.String(), sdk.NewDec(1).String()) weight = suite.app.SpendingKeeper.GetBeneficiaryWeight(suite.ctx, addrs[1], whitelistInfo) - suite.Require().Equal(weight, uint64(2)) + suite.Require().Equal(weight.String(), sdk.NewDec(2).String()) weight = suite.app.SpendingKeeper.GetBeneficiaryWeight(suite.ctx, addrs[2], whitelistInfo) - suite.Require().Equal(weight, uint64(0)) + suite.Require().Equal(weight.String(), sdk.NewDec(0).String()) } func (suite *KeeperTestSuite) TestIsAllowedBeneficiary() { @@ -122,8 +122,8 @@ func (suite *KeeperTestSuite) TestIsAllowedBeneficiary() { }) whitelistInfo := types.WeightedPermInfo{ - Roles: []types.WeightedRole{{Role: 1, Weight: 1}}, - Accounts: []types.WeightedAccount{{Account: addrs[1].String(), Weight: 2}}, + Roles: []types.WeightedRole{{Role: 1, Weight: sdk.NewDec(1)}}, + Accounts: []types.WeightedAccount{{Account: addrs[1].String(), Weight: sdk.NewDec(2)}}, } isAllowed := suite.app.SpendingKeeper.IsAllowedBeneficiary(suite.ctx, addrs[0], whitelistInfo) diff --git a/x/spending/keeper/spending_pool.go b/x/spending/keeper/spending_pool.go index 8ba74b67b..69d2bca2a 100644 --- a/x/spending/keeper/spending_pool.go +++ b/x/spending/keeper/spending_pool.go @@ -115,7 +115,7 @@ func (k Keeper) ClaimSpendingPool(ctx sdk.Context, poolName string, sender sdk.A } weight := k.GetBeneficiaryWeight(ctx, sender, *pool.Beneficiaries) - if weight == 0 { + if weight.IsZero() { return types.ErrNotPoolBeneficiary } @@ -150,7 +150,7 @@ func (k Keeper) ClaimSpendingPool(ctx sdk.Context, poolName string, sender sdk.A if duration > int64(pool.ClaimExpiry) { duration = int64(pool.ClaimExpiry) } - amount := rate.Amount.Mul(sdk.NewDec(duration * int64(weight))).RoundInt() + amount := rate.Amount.Mul(sdk.NewDec(duration)).Mul(weight).RoundInt() rewards = rewards.Add(sdk.NewCoin(rate.Denom, amount)) } diff --git a/x/spending/keeper/spending_pool_test.go b/x/spending/keeper/spending_pool_test.go index 43647b69d..c8bc63485 100644 --- a/x/spending/keeper/spending_pool_test.go +++ b/x/spending/keeper/spending_pool_test.go @@ -30,13 +30,13 @@ func (suite *KeeperTestSuite) TestSpendingPoolSetGet() { Roles: []types.WeightedRole{ { Role: 1, - Weight: 1, + Weight: sdk.NewDec(1), }, }, Accounts: []types.WeightedAccount{ { Account: addr1.String(), - Weight: 2, + Weight: sdk.NewDec(2), }, }, }, @@ -61,13 +61,13 @@ func (suite *KeeperTestSuite) TestSpendingPoolSetGet() { Roles: []types.WeightedRole{ { Role: 1, - Weight: 1, + Weight: sdk.NewDec(1), }, }, Accounts: []types.WeightedAccount{ { Account: addr1.String(), - Weight: 2, + Weight: sdk.NewDec(2), }, }, }, diff --git a/x/spending/types/genesis.go b/x/spending/types/genesis.go index a18fc2e89..c198bda53 100644 --- a/x/spending/types/genesis.go +++ b/x/spending/types/genesis.go @@ -19,7 +19,7 @@ func DefaultGenesis() *GenesisState { VoteEnactment: 300, // 300s Owners: &PermInfo{OwnerRoles: []uint64{govtypes.RoleValidator}}, Beneficiaries: &WeightedPermInfo{ - Roles: []WeightedRole{{govtypes.RoleValidator, 1}}, + Roles: []WeightedRole{{govtypes.RoleValidator, sdk.OneDec()}}, }, Balances: sdk.Coins{}, }, diff --git a/x/spending/types/msg.go b/x/spending/types/msg.go index 102c80947..181a29719 100644 --- a/x/spending/types/msg.go +++ b/x/spending/types/msg.go @@ -48,12 +48,12 @@ func (m *MsgCreateSpendingPool) ValidateBasic() error { return ErrEmptyProposerAccAddress } for _, beneficiary := range m.Beneficiaries.Accounts { - if beneficiary.Weight == 0 { + if beneficiary.Weight.IsNil() || beneficiary.Weight.IsZero() { return ErrEmptyWeightBeneficiary } } for _, beneficiary := range m.Beneficiaries.Roles { - if beneficiary.Weight == 0 { + if beneficiary.Weight.IsNil() || beneficiary.Weight.IsZero() { return ErrEmptyWeightBeneficiary } } diff --git a/x/spending/types/pool.pb.go b/x/spending/types/pool.pb.go index 01d1a407b..48888a480 100644 --- a/x/spending/types/pool.pb.go +++ b/x/spending/types/pool.pb.go @@ -138,8 +138,8 @@ func (m *PermInfo) GetOwnerAccounts() []string { } type WeightedRole struct { - Role uint64 `protobuf:"varint,1,opt,name=role,proto3" json:"role,omitempty"` - Weight uint64 `protobuf:"varint,2,opt,name=weight,proto3" json:"weight,omitempty"` + Role uint64 `protobuf:"varint,1,opt,name=role,proto3" json:"role,omitempty"` + Weight github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,2,opt,name=weight,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"weight"` } func (m *WeightedRole) Reset() { *m = WeightedRole{} } @@ -182,16 +182,9 @@ func (m *WeightedRole) GetRole() uint64 { return 0 } -func (m *WeightedRole) GetWeight() uint64 { - if m != nil { - return m.Weight - } - return 0 -} - type WeightedAccount struct { - Account string `protobuf:"bytes,1,opt,name=account,proto3" json:"account,omitempty"` - Weight uint64 `protobuf:"varint,2,opt,name=weight,proto3" json:"weight,omitempty"` + Account string `protobuf:"bytes,1,opt,name=account,proto3" json:"account,omitempty"` + Weight github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,2,opt,name=weight,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"weight"` } func (m *WeightedAccount) Reset() { *m = WeightedAccount{} } @@ -234,13 +227,6 @@ func (m *WeightedAccount) GetAccount() string { return "" } -func (m *WeightedAccount) GetWeight() uint64 { - if m != nil { - return m.Weight - } - return 0 -} - type WeightedPermInfo struct { Roles []WeightedRole `protobuf:"bytes,1,rep,name=roles,proto3" json:"roles"` Accounts []WeightedAccount `protobuf:"bytes,2,rep,name=accounts,proto3" json:"accounts"` @@ -446,51 +432,52 @@ func init() { func init() { proto.RegisterFile("kira/spending/pool.proto", fileDescriptor_6027931ab19c9a21) } var fileDescriptor_6027931ab19c9a21 = []byte{ - // 703 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x54, 0x4d, 0x6b, 0x1b, 0x3b, - 0x14, 0xf5, 0x24, 0x63, 0xc7, 0x96, 0xed, 0xbc, 0xf7, 0xf4, 0x1e, 0x2f, 0x22, 0xa1, 0xb6, 0x6b, - 0x28, 0x35, 0x85, 0x7a, 0x20, 0x5d, 0x14, 0x42, 0x17, 0xa9, 0x1d, 0x2f, 0x42, 0xa0, 0xa4, 0x93, - 0x42, 0x43, 0x37, 0x46, 0x1e, 0x2b, 0x13, 0x91, 0x19, 0x69, 0x3a, 0x92, 0x9b, 0xf8, 0x5f, 0x14, - 0xba, 0xed, 0xa2, 0x3f, 0x27, 0xcb, 0x2c, 0x4b, 0x17, 0xa1, 0x24, 0x9b, 0xae, 0xfb, 0x0b, 0x8a, - 0xee, 0x68, 0xfc, 0x51, 0x48, 0xe8, 0xca, 0x9a, 0x73, 0xcf, 0x3d, 0xba, 0x3a, 0x47, 0x16, 0x22, - 0x67, 0x3c, 0xa5, 0x9e, 0x4a, 0x98, 0x18, 0x73, 0x11, 0x7a, 0x89, 0x94, 0x51, 0x37, 0x49, 0xa5, - 0x96, 0xb8, 0x6e, 0x2a, 0xdd, 0xbc, 0xb2, 0xd9, 0x0c, 0xa5, 0x0c, 0x23, 0xe6, 0x41, 0x71, 0x34, - 0x39, 0xf1, 0x34, 0x8f, 0x99, 0xd2, 0x34, 0x4e, 0x32, 0xfe, 0xe6, 0x7f, 0xa1, 0x0c, 0x25, 0x2c, - 0x3d, 0xb3, 0xca, 0xd0, 0x36, 0x45, 0x95, 0x7e, 0x44, 0x79, 0xbc, 0x2f, 0x4e, 0x24, 0x26, 0x68, - 0x8d, 0x06, 0x81, 0x9c, 0x08, 0x4d, 0x9c, 0x96, 0xd3, 0xa9, 0xf8, 0xf9, 0x27, 0xde, 0x42, 0x15, - 0xb3, 0xf5, 0x50, 0xd0, 0x98, 0x91, 0x15, 0xa8, 0x95, 0x0d, 0xf0, 0x8a, 0xc6, 0x0c, 0x3f, 0x40, - 0x28, 0xa2, 0x4a, 0x0f, 0x03, 0x23, 0x44, 0x56, 0x5b, 0x4e, 0xc7, 0xf5, 0x2b, 0x06, 0x01, 0xe5, - 0xf6, 0x31, 0x2a, 0x1f, 0xb2, 0x34, 0xdb, 0xa1, 0x89, 0xaa, 0xf2, 0x5c, 0xb0, 0x74, 0x98, 0xca, - 0x88, 0x29, 0xe2, 0xb4, 0x56, 0x3b, 0xae, 0x8f, 0x00, 0xf2, 0x0d, 0x82, 0x1f, 0xa1, 0xf5, 0x8c, - 0x60, 0x77, 0x56, 0x64, 0xa5, 0xb5, 0xda, 0xa9, 0xf8, 0x75, 0x40, 0x5f, 0x5a, 0x70, 0xc7, 0xfd, - 0xf1, 0xa5, 0xe9, 0xb4, 0x77, 0x51, 0xed, 0x2d, 0xe3, 0xe1, 0xa9, 0x66, 0x63, 0xd3, 0x8d, 0x31, - 0x72, 0x8d, 0x2e, 0x0c, 0xef, 0xfa, 0xb0, 0xc6, 0xff, 0xa3, 0xd2, 0x39, 0x70, 0x60, 0x6c, 0xd7, - 0xb7, 0x5f, 0x56, 0x61, 0x1f, 0xfd, 0x95, 0x2b, 0x58, 0xed, 0x7b, 0x4c, 0xb8, 0x5f, 0xea, 0x93, - 0x83, 0xfe, 0xce, 0xb5, 0x66, 0xe7, 0x7d, 0x8e, 0x8a, 0xf3, 0x93, 0x56, 0xb7, 0xb7, 0xba, 0x4b, - 0xa1, 0x75, 0x17, 0xa7, 0xef, 0xb9, 0x97, 0xd7, 0xcd, 0x82, 0x9f, 0xf1, 0xf1, 0x2e, 0x2a, 0x2f, - 0x39, 0x50, 0xdd, 0x6e, 0xdc, 0xd1, 0x6b, 0xe7, 0xb6, 0xed, 0xb3, 0x2e, 0x3b, 0xd5, 0xe7, 0x22, - 0xaa, 0x1d, 0xd9, 0x96, 0x43, 0x29, 0x23, 0xe3, 0x11, 0x84, 0x98, 0x9d, 0x0d, 0xd6, 0x26, 0x15, - 0xc8, 0x6e, 0xa8, 0x34, 0x4d, 0xf3, 0xd3, 0x21, 0x80, 0x8e, 0x0c, 0x62, 0xe2, 0xcf, 0x08, 0x4c, - 0x8c, 0x6d, 0xc0, 0x65, 0x00, 0x06, 0x62, 0x8c, 0x1f, 0xa2, 0x9a, 0x2d, 0x5e, 0x24, 0x3c, 0x9d, - 0x12, 0x17, 0xea, 0x99, 0xe2, 0x00, 0x20, 0x7c, 0x8c, 0x8a, 0x29, 0xd5, 0x4c, 0x91, 0xa2, 0x09, - 0xb3, 0xd7, 0x33, 0xa3, 0x7e, 0xbb, 0x6e, 0x3e, 0x09, 0xb9, 0x3e, 0x9d, 0x8c, 0xba, 0x81, 0x8c, - 0xbd, 0x40, 0xaa, 0x58, 0x2a, 0xfb, 0xf3, 0x54, 0x8d, 0xcf, 0x3c, 0x3d, 0x4d, 0x98, 0xea, 0xee, - 0xb1, 0xa0, 0x2f, 0xb9, 0xf8, 0x79, 0xdd, 0xac, 0x4d, 0x69, 0x1c, 0xed, 0xb4, 0x41, 0xa8, 0xed, - 0x67, 0x82, 0x66, 0xf4, 0x0f, 0x52, 0xb3, 0xe1, 0xfb, 0x89, 0x4c, 0x27, 0x31, 0x29, 0x65, 0xa3, - 0x1b, 0xe8, 0x35, 0x20, 0x33, 0x42, 0xc2, 0x52, 0x2e, 0xc7, 0x64, 0x6d, 0x4e, 0x38, 0x04, 0xc4, - 0xdc, 0x38, 0x20, 0x30, 0x41, 0x03, 0x1d, 0x33, 0xa1, 0x49, 0x19, 0x38, 0x75, 0x83, 0x0e, 0x72, - 0x10, 0x7b, 0xa8, 0x04, 0x57, 0x50, 0x91, 0x4a, 0xcb, 0xe9, 0x54, 0xb7, 0x37, 0x7e, 0x8b, 0x23, - 0x8f, 0xdc, 0xb7, 0x34, 0x3c, 0x40, 0xf5, 0x11, 0x13, 0xec, 0x84, 0x07, 0x9c, 0xa6, 0x9c, 0x29, - 0x82, 0xa0, 0xaf, 0x79, 0x47, 0x8c, 0xb3, 0xfe, 0xe5, 0x2e, 0x7c, 0x80, 0xca, 0x23, 0x1a, 0x51, - 0x11, 0x30, 0x45, 0xaa, 0xe0, 0x9e, 0x67, 0xdd, 0x7b, 0xfc, 0x07, 0xee, 0x19, 0xeb, 0xfc, 0x99, - 0x80, 0x89, 0x6a, 0x3c, 0x15, 0x34, 0xe6, 0xc1, 0xd0, 0xd8, 0x47, 0x6a, 0x2d, 0xa7, 0x53, 0xf6, - 0xab, 0x16, 0xf3, 0xa9, 0x66, 0xb8, 0x8b, 0xfe, 0x5d, 0xa4, 0xe4, 0xbe, 0xd5, 0xc1, 0x93, 0x7f, - 0x16, 0x98, 0xd6, 0xbe, 0x17, 0x68, 0x0b, 0xfe, 0xfc, 0x4b, 0x4d, 0x01, 0x8d, 0x82, 0xa1, 0x79, - 0x80, 0xc8, 0x3a, 0xf4, 0x6d, 0x18, 0xca, 0xde, 0xbc, 0xb7, 0x4f, 0xa3, 0xe0, 0x0d, 0x8f, 0x59, - 0x6f, 0xef, 0xf2, 0xa6, 0xe1, 0x5c, 0xdd, 0x34, 0x9c, 0xef, 0x37, 0x0d, 0xe7, 0xe3, 0x6d, 0xa3, - 0x70, 0x75, 0xdb, 0x28, 0x7c, 0xbd, 0x6d, 0x14, 0xde, 0x2d, 0xde, 0x8d, 0x03, 0x9e, 0xd2, 0xbe, - 0x4c, 0x99, 0xa7, 0xd8, 0x19, 0xe5, 0xde, 0xc5, 0xfc, 0x3d, 0x84, 0x53, 0x8e, 0x4a, 0xf0, 0x96, - 0x3d, 0xfb, 0x15, 0x00, 0x00, 0xff, 0xff, 0xd4, 0x60, 0xba, 0x37, 0x2d, 0x05, 0x00, 0x00, + // 714 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x54, 0x4d, 0x6b, 0x1b, 0x49, + 0x10, 0xd5, 0xd8, 0x23, 0x59, 0x6a, 0x49, 0xde, 0xdd, 0xde, 0x05, 0x37, 0x36, 0x2b, 0x29, 0x82, + 0x24, 0x22, 0x90, 0x19, 0x70, 0x0e, 0x01, 0x93, 0x43, 0x22, 0x59, 0x81, 0x60, 0x08, 0xce, 0x38, + 0x10, 0x93, 0x8b, 0x68, 0x8d, 0xda, 0x72, 0xe3, 0x99, 0xee, 0xc9, 0x74, 0x2b, 0xb6, 0xfe, 0x45, + 0x20, 0xd7, 0x1c, 0xf2, 0x73, 0x7c, 0xf4, 0x31, 0xe4, 0x60, 0x82, 0x7d, 0xc9, 0x39, 0xbf, 0x20, + 0x74, 0x4d, 0x8f, 0x3e, 0x02, 0x0e, 0x3e, 0xe4, 0xa4, 0xd6, 0xab, 0xf7, 0xaa, 0x6a, 0x5e, 0x15, + 0x85, 0xc8, 0x09, 0x4f, 0xa9, 0xaf, 0x12, 0x26, 0x46, 0x5c, 0x8c, 0xfd, 0x44, 0xca, 0xc8, 0x4b, + 0x52, 0xa9, 0x25, 0xae, 0x9b, 0x88, 0x97, 0x47, 0x36, 0x9b, 0x63, 0x29, 0xc7, 0x11, 0xf3, 0x21, + 0x38, 0x9c, 0x1c, 0xf9, 0x9a, 0xc7, 0x4c, 0x69, 0x1a, 0x27, 0x19, 0x7f, 0xf3, 0xbf, 0xb1, 0x1c, + 0x4b, 0x78, 0xfa, 0xe6, 0x95, 0xa1, 0x6d, 0x8a, 0x2a, 0xbd, 0x88, 0xf2, 0xf8, 0x85, 0x38, 0x92, + 0x98, 0xa0, 0x35, 0x1a, 0x86, 0x72, 0x22, 0x34, 0x71, 0x5a, 0x4e, 0xa7, 0x12, 0xe4, 0x7f, 0xf1, + 0x16, 0xaa, 0x98, 0xd2, 0x03, 0x41, 0x63, 0x46, 0x56, 0x20, 0x56, 0x36, 0xc0, 0x4b, 0x1a, 0x33, + 0xfc, 0x3f, 0x42, 0x11, 0x55, 0x7a, 0x10, 0x9a, 0x44, 0x64, 0xb5, 0xe5, 0x74, 0xdc, 0xa0, 0x62, + 0x10, 0xc8, 0xdc, 0x3e, 0x44, 0xe5, 0x7d, 0x96, 0x66, 0x15, 0x9a, 0xa8, 0x2a, 0x4f, 0x05, 0x4b, + 0x07, 0xa9, 0x8c, 0x98, 0x22, 0x4e, 0x6b, 0xb5, 0xe3, 0x06, 0x08, 0xa0, 0xc0, 0x20, 0xf8, 0x2e, + 0x5a, 0xcf, 0x08, 0xb6, 0xb2, 0x22, 0x2b, 0xad, 0xd5, 0x4e, 0x25, 0xa8, 0x03, 0xfa, 0xcc, 0x82, + 0x3b, 0xee, 0xf7, 0xcf, 0x4d, 0xa7, 0x9d, 0xa0, 0xda, 0x1b, 0xc6, 0xc7, 0xc7, 0x9a, 0x8d, 0x8c, + 0x1a, 0x63, 0xe4, 0x9a, 0xbc, 0xd0, 0xbc, 0x1b, 0xc0, 0x1b, 0x3f, 0x47, 0xa5, 0x53, 0xe0, 0x64, + 0x6d, 0x77, 0xbd, 0xf3, 0xcb, 0x66, 0xe1, 0xeb, 0x65, 0xf3, 0xde, 0x98, 0xeb, 0xe3, 0xc9, 0xd0, + 0x0b, 0x65, 0xec, 0x87, 0x52, 0xc5, 0x52, 0xd9, 0x9f, 0x87, 0x6a, 0x74, 0xe2, 0xeb, 0x69, 0xc2, + 0x94, 0xb7, 0xcb, 0xc2, 0xc0, 0xaa, 0x6d, 0xc5, 0x29, 0xfa, 0x2b, 0xaf, 0x68, 0x7b, 0xf9, 0x8d, + 0x69, 0x7f, 0xb6, 0xf4, 0x47, 0x07, 0xfd, 0x9d, 0xd7, 0x9e, 0xf9, 0xf9, 0x18, 0x15, 0xe7, 0x4e, + 0x56, 0xb7, 0xb7, 0xbc, 0xa5, 0xa5, 0xf0, 0x16, 0xdd, 0xe9, 0xba, 0xa6, 0x7c, 0x90, 0xf1, 0xf1, + 0x53, 0x54, 0x5e, 0x72, 0xb8, 0xba, 0xdd, 0xb8, 0x41, 0x6b, 0xbf, 0xd3, 0xca, 0x67, 0x2a, 0xdb, + 0xd5, 0xa7, 0x22, 0xaa, 0x1d, 0x58, 0xc9, 0xbe, 0x94, 0x91, 0x99, 0x01, 0x2c, 0x49, 0xe6, 0x05, + 0xbc, 0xcd, 0xd4, 0x61, 0x37, 0x06, 0x4a, 0xd3, 0x34, 0x73, 0xc3, 0x0d, 0x10, 0x40, 0x07, 0x06, + 0x31, 0xeb, 0x95, 0x11, 0x98, 0x18, 0xd9, 0x05, 0x2a, 0x03, 0xd0, 0x17, 0x23, 0x7c, 0x07, 0xd5, + 0x6c, 0xf0, 0x2c, 0xe1, 0xe9, 0x94, 0xb8, 0x10, 0xcf, 0x32, 0xf6, 0x01, 0xc2, 0x87, 0xa8, 0x98, + 0x52, 0xcd, 0x14, 0x29, 0x9a, 0x65, 0xe9, 0x76, 0xad, 0xd1, 0x0f, 0x6e, 0x67, 0x74, 0x4f, 0x72, + 0xf1, 0xe3, 0xb2, 0x59, 0x9b, 0xd2, 0x38, 0xda, 0x69, 0x43, 0xa2, 0x76, 0x90, 0x25, 0x34, 0xad, + 0xbf, 0x97, 0x9a, 0x0d, 0xde, 0x4d, 0x64, 0x3a, 0x89, 0x49, 0x29, 0x6b, 0xdd, 0x40, 0xaf, 0x00, + 0x99, 0x11, 0x12, 0x96, 0x72, 0x39, 0x22, 0x6b, 0x73, 0xc2, 0x3e, 0x20, 0x66, 0xa3, 0x81, 0xc0, + 0x04, 0x0d, 0x75, 0xcc, 0x84, 0x26, 0x65, 0xe0, 0xd4, 0x0d, 0xda, 0xcf, 0x41, 0xec, 0xa3, 0x12, + 0xac, 0xb8, 0x22, 0x95, 0x96, 0xd3, 0xa9, 0x6e, 0x6f, 0xfc, 0x32, 0x8e, 0x7c, 0xe4, 0x81, 0xa5, + 0xe1, 0x3e, 0xaa, 0x0f, 0x99, 0x60, 0x47, 0x3c, 0xe4, 0x34, 0xe5, 0x4c, 0x11, 0x04, 0xba, 0xe6, + 0x0d, 0x63, 0x9c, 0xe9, 0x97, 0x55, 0x78, 0x0f, 0x95, 0x87, 0x34, 0xa2, 0x22, 0x64, 0x8a, 0x54, + 0xc1, 0x3d, 0xdf, 0xba, 0x77, 0xff, 0x16, 0xee, 0x19, 0xeb, 0x82, 0x59, 0x02, 0x33, 0xaa, 0xd1, + 0x54, 0xd0, 0x98, 0x87, 0x03, 0x63, 0x1f, 0xa9, 0xb5, 0x9c, 0x4e, 0x39, 0xa8, 0x5a, 0x2c, 0xa0, + 0x9a, 0x61, 0x0f, 0xfd, 0xbb, 0x48, 0xc9, 0x7d, 0xab, 0x83, 0x27, 0xff, 0x2c, 0x30, 0xad, 0x7d, + 0x4f, 0xd0, 0x16, 0x1c, 0x97, 0x25, 0x51, 0x48, 0xa3, 0x70, 0x60, 0x0e, 0x1c, 0x59, 0x07, 0xdd, + 0x86, 0xa1, 0xec, 0xce, 0xb5, 0x3d, 0x1a, 0x85, 0xaf, 0x79, 0xcc, 0xba, 0xbb, 0xe7, 0x57, 0x0d, + 0xe7, 0xe2, 0xaa, 0xe1, 0x7c, 0xbb, 0x6a, 0x38, 0x1f, 0xae, 0x1b, 0x85, 0x8b, 0xeb, 0x46, 0xe1, + 0xcb, 0x75, 0xa3, 0xf0, 0x76, 0x71, 0x37, 0xf6, 0x78, 0x4a, 0x7b, 0x32, 0x65, 0xbe, 0x62, 0x27, + 0x94, 0xfb, 0x67, 0xf3, 0x7b, 0x0b, 0x5f, 0x39, 0x2c, 0xc1, 0xad, 0x7c, 0xf4, 0x33, 0x00, 0x00, + 0xff, 0xff, 0xc4, 0xc1, 0x51, 0x35, 0x8d, 0x05, 0x00, 0x00, } func (this *PermInfo) Equal(that interface{}) bool { @@ -552,7 +539,7 @@ func (this *WeightedRole) Equal(that interface{}) bool { if this.Role != that1.Role { return false } - if this.Weight != that1.Weight { + if !this.Weight.Equal(that1.Weight) { return false } return true @@ -579,7 +566,7 @@ func (this *WeightedAccount) Equal(that interface{}) bool { if this.Account != that1.Account { return false } - if this.Weight != that1.Weight { + if !this.Weight.Equal(that1.Weight) { return false } return true @@ -733,11 +720,16 @@ func (m *WeightedRole) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - if m.Weight != 0 { - i = encodeVarintPool(dAtA, i, uint64(m.Weight)) - i-- - dAtA[i] = 0x10 + { + size := m.Weight.Size() + i -= size + if _, err := m.Weight.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintPool(dAtA, i, uint64(size)) } + i-- + dAtA[i] = 0x12 if m.Role != 0 { i = encodeVarintPool(dAtA, i, uint64(m.Role)) i-- @@ -766,11 +758,16 @@ func (m *WeightedAccount) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - if m.Weight != 0 { - i = encodeVarintPool(dAtA, i, uint64(m.Weight)) - i-- - dAtA[i] = 0x10 + { + size := m.Weight.Size() + i -= size + if _, err := m.Weight.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintPool(dAtA, i, uint64(size)) } + i-- + dAtA[i] = 0x12 if len(m.Account) > 0 { i -= len(m.Account) copy(dAtA[i:], m.Account) @@ -1026,9 +1023,8 @@ func (m *WeightedRole) Size() (n int) { if m.Role != 0 { n += 1 + sovPool(uint64(m.Role)) } - if m.Weight != 0 { - n += 1 + sovPool(uint64(m.Weight)) - } + l = m.Weight.Size() + n += 1 + l + sovPool(uint64(l)) return n } @@ -1042,9 +1038,8 @@ func (m *WeightedAccount) Size() (n int) { if l > 0 { n += 1 + l + sovPool(uint64(l)) } - if m.Weight != 0 { - n += 1 + sovPool(uint64(m.Weight)) - } + l = m.Weight.Size() + n += 1 + l + sovPool(uint64(l)) return n } @@ -1475,10 +1470,10 @@ func (m *WeightedRole) Unmarshal(dAtA []byte) error { } } case 2: - if wireType != 0 { + if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Weight", wireType) } - m.Weight = 0 + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowPool @@ -1488,11 +1483,26 @@ func (m *WeightedRole) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Weight |= uint64(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthPool + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthPool + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Weight.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipPool(dAtA[iNdEx:]) @@ -1576,10 +1586,10 @@ func (m *WeightedAccount) Unmarshal(dAtA []byte) error { m.Account = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: - if wireType != 0 { + if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Weight", wireType) } - m.Weight = 0 + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowPool @@ -1589,11 +1599,26 @@ func (m *WeightedAccount) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Weight |= uint64(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthPool + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthPool + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Weight.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipPool(dAtA[iNdEx:]) From 1d67308ccd40dfc0432d93654f1b777e8f79ea1d Mon Sep 17 00:00:00 2001 From: jgo121 Date: Fri, 17 Nov 2023 20:16:34 +0800 Subject: [PATCH 8/8] add release version for basket module and spending module updates --- RELEASE.md | 3 ++- types/constants.go | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/RELEASE.md b/RELEASE.md index 05bc4827d..dc5925525 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -1,3 +1,4 @@ Features: -- Resolve claim undelegation issue +- Basket module enhancement for #441 #590 #591 #592 #594 +- Spending module enhancement for #597 diff --git a/types/constants.go b/types/constants.go index 7336de881..d90b918a2 100644 --- a/types/constants.go +++ b/types/constants.go @@ -3,6 +3,6 @@ package types const ( // we set page iteration limit for safety PageIterationLimit = 512 - SekaiVersion = "v0.3.36" + SekaiVersion = "v0.3.37" CosmosVersion = "v0.47.5" )