From 4294b9256b83d83a85376a61064900da47b2b128 Mon Sep 17 00:00:00 2001 From: stackman27 Date: Tue, 6 Sep 2022 18:03:04 -0700 Subject: [PATCH 1/3] Module Wired up and created MsgSetValidatorSetPreference --- app/keepers/keepers.go | 13 + osmoutils/slice_helper.go | 16 + .../v1beta1/genesis.proto | 15 + .../validator-preference/v1beta1/params.proto | 17 + x/validator-preference/genesis.go | 20 + x/validator-preference/keeper.go | 77 ++++ x/validator-preference/keeper_test.go | 52 +++ x/validator-preference/msg_server.go | 72 ++++ x/validator-preference/msg_server_test.go | 124 +++++++ x/validator-preference/types/codec.go | 29 ++ x/validator-preference/types/errors.go | 1 + .../types/expected_interfaces.go | 27 ++ x/validator-preference/types/genesis.go | 17 + x/validator-preference/types/genesis.pb.go | 321 +++++++++++++++++ x/validator-preference/types/keys.go | 18 + x/validator-preference/types/msgs.go | 146 ++++++++ x/validator-preference/types/msgs_test.go | 133 +++++++ x/validator-preference/types/params.go | 62 ++++ x/validator-preference/types/params.pb.go | 341 ++++++++++++++++++ x/validator-preference/validator_set.go | 81 +++++ .../valpref-module/module.go | 204 +++++++++++ 21 files changed, 1786 insertions(+) create mode 100644 proto/osmosis/validator-preference/v1beta1/genesis.proto create mode 100644 proto/osmosis/validator-preference/v1beta1/params.proto create mode 100644 x/validator-preference/genesis.go create mode 100644 x/validator-preference/keeper.go create mode 100644 x/validator-preference/keeper_test.go create mode 100644 x/validator-preference/msg_server.go create mode 100644 x/validator-preference/msg_server_test.go create mode 100644 x/validator-preference/types/codec.go create mode 100644 x/validator-preference/types/errors.go create mode 100644 x/validator-preference/types/expected_interfaces.go create mode 100644 x/validator-preference/types/genesis.go create mode 100644 x/validator-preference/types/genesis.pb.go create mode 100644 x/validator-preference/types/keys.go create mode 100644 x/validator-preference/types/msgs.go create mode 100644 x/validator-preference/types/msgs_test.go create mode 100644 x/validator-preference/types/params.go create mode 100644 x/validator-preference/types/params.pb.go create mode 100644 x/validator-preference/validator_set.go create mode 100644 x/validator-preference/valpref-module/module.go diff --git a/app/keepers/keepers.go b/app/keepers/keepers.go index 83c53e3f2cd..ab7d8fd1ca0 100644 --- a/app/keepers/keepers.go +++ b/app/keepers/keepers.go @@ -75,6 +75,8 @@ import ( "github.com/osmosis-labs/osmosis/v12/x/txfees" txfeeskeeper "github.com/osmosis-labs/osmosis/v12/x/txfees/keeper" txfeestypes "github.com/osmosis-labs/osmosis/v12/x/txfees/types" + validatorpreference "github.com/osmosis-labs/osmosis/v12/x/validator-preference" + validatorpreferencetypes "github.com/osmosis-labs/osmosis/v12/x/validator-preference/types" ) type AppKeepers struct { @@ -338,6 +340,16 @@ func (appKeepers *AppKeepers) InitNormalKeepers( ) appKeepers.TokenFactoryKeeper = &tokenFactoryKeeper + validatorPreferenceKeeper := validatorpreference.NewKeeper( + appKeepers.keys[validatorpreferencetypes.StoreKey], + appKeepers.GetSubspace(validatorpreferencetypes.ModuleName), + appKeepers.StakingKeeper, + appKeepers.BankKeeper, + appKeepers.DistrKeeper, + ) + + appKeepers.ValidatorPreferenceKeeper = &validatorPreferenceKeeper + // The last arguments can contain custom message handlers, and custom query handlers, // if we want to allow any custom callbacks supportedFeatures := "iterator,staking,stargate,osmosis" @@ -556,5 +568,6 @@ func KVStoreKeys() []string { superfluidtypes.StoreKey, wasm.StoreKey, tokenfactorytypes.StoreKey, + validatorpreferencetypes.StoreKey, } } diff --git a/osmoutils/slice_helper.go b/osmoutils/slice_helper.go index f4c14a7b975..913eb1c7254 100644 --- a/osmoutils/slice_helper.go +++ b/osmoutils/slice_helper.go @@ -4,6 +4,7 @@ import ( "sort" "golang.org/x/exp/constraints" + ) // SortSlice sorts a slice of type T elements that implement constraints.Ordered. @@ -35,3 +36,18 @@ func ReverseSlice[T any](s []T) []T { } return s } + +// ContainsDuplicate checks if there are any duplicate +// elements in the slice. +func ContainsDuplicate[T any](arr []T) bool { + visited := make(map[any]bool, 0) + for i := 0; i < len(arr); i++ { + if visited[arr[i]] { + return true + } else { + visited[arr[i]] = true + } + } + return false +} + diff --git a/proto/osmosis/validator-preference/v1beta1/genesis.proto b/proto/osmosis/validator-preference/v1beta1/genesis.proto new file mode 100644 index 00000000000..47d11cb652c --- /dev/null +++ b/proto/osmosis/validator-preference/v1beta1/genesis.proto @@ -0,0 +1,15 @@ +syntax = "proto3"; +package osmosis.validatorpreference.v1beta1; + +import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; +import "osmosis/validator-preference/v1beta1/params.proto"; + +option go_package = "github.com/osmosis-labs/osmosis/v12/x/validator-preference/types"; +option (gogoproto.goproto_getters_all) = false; + +// GenesisState defines the validator-set preference module's genesis state. +message GenesisState { + // params defines the paramaters of the module. + Params params = 1 [ (gogoproto.nullable) = false ]; +} diff --git a/proto/osmosis/validator-preference/v1beta1/params.proto b/proto/osmosis/validator-preference/v1beta1/params.proto new file mode 100644 index 00000000000..454c99b24ad --- /dev/null +++ b/proto/osmosis/validator-preference/v1beta1/params.proto @@ -0,0 +1,17 @@ +syntax = "proto3"; +package osmosis.validatorpreference.v1beta1; + +import "gogoproto/gogo.proto"; +import "cosmos_proto/cosmos.proto"; +import "cosmos/base/v1beta1/coin.proto"; + +option go_package = "github.com/osmosis-labs/osmosis/v12/x/validator-preference/types"; + +// Params defines the parameters for the module. +message Params { + repeated cosmos.base.v1beta1.Coin valset_creation_fee = 1 [ + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", + (gogoproto.moretags) = "yaml:\"valset_creation_fee\"", + (gogoproto.nullable) = false + ]; +} diff --git a/x/validator-preference/genesis.go b/x/validator-preference/genesis.go new file mode 100644 index 00000000000..375735b7ee0 --- /dev/null +++ b/x/validator-preference/genesis.go @@ -0,0 +1,20 @@ +package keeper + +import ( + "github.com/osmosis-labs/osmosis/v12/x/validator-preference/types" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// InitGenesis initializes the capability module's state from a provided genesis +// state. +func (k Keeper) InitGenesis(ctx sdk.Context, genState types.GenesisState) { + k.SetParams(ctx, genState.Params) +} + +// ExportGenesis returns the capability module's exported genesis. +func (k Keeper) ExportGenesis(ctx sdk.Context) *types.GenesisState { + return &types.GenesisState{ + Params: k.GetParams(ctx), + } +} diff --git a/x/validator-preference/keeper.go b/x/validator-preference/keeper.go new file mode 100644 index 00000000000..2ea82aa35b7 --- /dev/null +++ b/x/validator-preference/keeper.go @@ -0,0 +1,77 @@ +package keeper + +import ( + "fmt" + + "github.com/tendermint/tendermint/libs/log" + + sdk "github.com/cosmos/cosmos-sdk/types" + paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" + "github.com/gogo/protobuf/proto" + "github.com/osmosis-labs/osmosis/v12/osmoutils" + "github.com/osmosis-labs/osmosis/v12/x/validator-preference/types" +) + +type Keeper struct { + storeKey sdk.StoreKey + paramSpace paramtypes.Subspace + stakingKeeper types.StakingInterface + bankKeeper types.BankInterface + distrKeeper types.DistrInterface +} + +func NewKeeper(storeKey sdk.StoreKey, + paramSpace paramtypes.Subspace, + stakingKeeper types.StakingInterface, + bankKeeper types.BankInterface, + distrKeeper types.DistrInterface, +) Keeper { + if !paramSpace.HasKeyTable() { + paramSpace = paramSpace.WithKeyTable(types.ParamKeyTable()) + } + + return Keeper{ + storeKey: storeKey, + paramSpace: paramSpace, + stakingKeeper: stakingKeeper, + bankKeeper: bankKeeper, + distrKeeper: distrKeeper, + } +} + +func (k Keeper) Logger(ctx sdk.Context) log.Logger { + return ctx.Logger().With("module", fmt.Sprintf("x/%s", types.ModuleName)) +} + +func (k Keeper) SetValidatorSetPreferences(ctx sdk.Context, delegator string, validators types.ValidatorSetPreferences) { + store := ctx.KVStore(k.storeKey) + osmoutils.MustSet(store, []byte(delegator), &validators) +} + +func (k Keeper) GetValidatorSetPreference(ctx sdk.Context, delegator string) (types.ValidatorSetPreferences, bool) { + validatorSet := types.ValidatorSetPreferences{} + + store := ctx.KVStore(k.storeKey) + b := store.Get([]byte(delegator)) + if b == nil { + return types.ValidatorSetPreferences{}, false + } + + err := proto.Unmarshal(b, &validatorSet) + if err != nil { + return types.ValidatorSetPreferences{}, false + } + + return validatorSet, true +} + +// GetParams returns the total set params. +func (k Keeper) GetParams(ctx sdk.Context) (params types.Params) { + k.paramSpace.GetParamSet(ctx, ¶ms) + return params +} + +// SetParams sets the total set of params. +func (k Keeper) SetParams(ctx sdk.Context, params types.Params) { + k.paramSpace.SetParamSet(ctx, ¶ms) +} diff --git a/x/validator-preference/keeper_test.go b/x/validator-preference/keeper_test.go new file mode 100644 index 00000000000..795a6aaca62 --- /dev/null +++ b/x/validator-preference/keeper_test.go @@ -0,0 +1,52 @@ +package keeper_test + +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + "github.com/osmosis-labs/osmosis/v12/app/apptesting" + "github.com/osmosis-labs/osmosis/v12/x/validator-preference/types" + "github.com/stretchr/testify/suite" +) + +type KeeperTestSuite struct { + apptesting.KeeperTestHelper +} + +func (suite *KeeperTestSuite) SetupTest() { + suite.Setup() +} + +// SetupMultipleValidators setups "numValidator" validators and returns their address in string +func (suite *KeeperTestSuite) SetupMultipleValidators(numValidator int) []string { + valAddrs := []string{} + for i := 0; i < numValidator; i++ { + valAddr := suite.SetupValidator(stakingtypes.Bonded) + valAddrs = append(valAddrs, valAddr.String()) + } + return valAddrs +} + +func (suite *KeeperTestSuite) PrepareDelegateToValidatorSet() []types.ValidatorPreference { + valAddrs := suite.SetupMultipleValidators(3) + valPreferences := []types.ValidatorPreference{ + { + ValOperAddress: valAddrs[0], + Weight: sdk.NewDecWithPrec(5, 1), + }, + { + ValOperAddress: valAddrs[1], + Weight: sdk.NewDecWithPrec(3, 1), + }, + { + ValOperAddress: valAddrs[2], + Weight: sdk.NewDecWithPrec(2, 1), + }, + } + return valPreferences +} + +func TestKeeperTestSuite(t *testing.T) { + suite.Run(t, new(KeeperTestSuite)) +} diff --git a/x/validator-preference/msg_server.go b/x/validator-preference/msg_server.go new file mode 100644 index 00000000000..aa921501e4c --- /dev/null +++ b/x/validator-preference/msg_server.go @@ -0,0 +1,72 @@ +package keeper + +import ( + "context" + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/osmosis-labs/osmosis/v12/x/validator-preference/types" +) + +type msgServer struct { + keeper *Keeper +} + +// NewMsgServerImpl returns an implementation of the MsgServer interface +// for the provided Keeper. +func NewMsgServerImpl(keeper *Keeper) types.MsgServer { + return &msgServer{ + keeper: keeper, + } +} + +var _ types.MsgServer = msgServer{} + +func (server msgServer) SetValidatorSetPreference(goCtx context.Context, msg *types.MsgSetValidatorSetPreference) (*types.MsgSetValidatorSetPreferenceResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + + // new user preference + preferences := msg.Preferences + + // check if a user already has a validator-set created + existingValidators, found := server.keeper.GetValidatorSetPreference(ctx, msg.Delegator) + if found { + // check if the new preferences is the same as the existing preferences + isEqual := server.keeper.SortAndCompareValidatorSet(preferences, existingValidators.Preferences) + if isEqual { + return nil, fmt.Errorf("The preferences (validator and weights) are the same") + } + } + + // checks that all the validators exist on chain + err := server.keeper.ValidatePreferences(ctx, preferences) + if err != nil { + return nil, err + } + + // charge fee to execute this message + err = server.keeper.ChargeForCreateValSet(ctx, msg.Delegator) + if err != nil { + return nil, err + } + + // create/update the validator-set based on what user provides + setMsg := types.ValidatorSetPreferences{ + Preferences: msg.Preferences, + } + + server.keeper.SetValidatorSetPreferences(ctx, msg.Delegator, setMsg) + return &types.MsgSetValidatorSetPreferenceResponse{}, nil +} + +func (server msgServer) DelegateToValidatorSet(goCtx context.Context, msg *types.MsgDelegateToValidatorSet) (*types.MsgDelegateToValidatorSetResponse, error) { + return &types.MsgDelegateToValidatorSetResponse{}, nil +} + +func (server msgServer) UndelegateFromValidatorSet(goCtx context.Context, msg *types.MsgUndelegateFromValidatorSet) (*types.MsgUndelegateFromValidatorSetResponse, error) { + return &types.MsgUndelegateFromValidatorSetResponse{}, nil +} + +func (server msgServer) WithdrawDelegationRewards(goCtx context.Context, msg *types.MsgWithdrawDelegationRewards) (*types.MsgWithdrawDelegationRewardsResponse, error) { + return &types.MsgWithdrawDelegationRewardsResponse{}, nil +} diff --git a/x/validator-preference/msg_server_test.go b/x/validator-preference/msg_server_test.go new file mode 100644 index 00000000000..966764e3ee4 --- /dev/null +++ b/x/validator-preference/msg_server_test.go @@ -0,0 +1,124 @@ +package keeper_test + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + valPref "github.com/osmosis-labs/osmosis/v12/x/validator-preference" + "github.com/osmosis-labs/osmosis/v12/x/validator-preference/types" +) + +func (suite *KeeperTestSuite) TestSetValidatorSetPreference() { + suite.SetupTest() + + // setup 3 validators + valAddrs := suite.SetupMultipleValidators(3) + + tests := []struct { + name string + delegator sdk.AccAddress + preferences []types.ValidatorPreference + creationFee sdk.Coins + expectPass bool + }{ + { + name: "creation of new validator set", + delegator: sdk.AccAddress([]byte("addr1---------------")), + preferences: []types.ValidatorPreference{ + { + ValOperAddress: valAddrs[0], + Weight: sdk.NewDecWithPrec(5, 1), + }, + { + ValOperAddress: valAddrs[1], + Weight: sdk.NewDecWithPrec(3, 1), + }, + { + ValOperAddress: valAddrs[2], + Weight: sdk.NewDecWithPrec(2, 1), + }, + }, + creationFee: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(10))), + expectPass: true, + }, + { + name: "update existing validator with same values as previous one", + delegator: sdk.AccAddress([]byte("addr1---------------")), + preferences: []types.ValidatorPreference{ + { + ValOperAddress: valAddrs[1], + Weight: sdk.NewDecWithPrec(3, 1), + }, + { + ValOperAddress: valAddrs[0], + Weight: sdk.NewDecWithPrec(5, 1), + }, + { + ValOperAddress: valAddrs[2], + Weight: sdk.NewDecWithPrec(2, 1), + }, + }, + creationFee: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(10))), + expectPass: false, + }, + { + name: "create validator set with unknown validator address", + delegator: sdk.AccAddress([]byte("addr2---------------")), + preferences: []types.ValidatorPreference{ + { + ValOperAddress: "addr1---------------", + Weight: sdk.NewDec(1), + }, + }, + creationFee: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(10))), + expectPass: false, + }, + { + name: "creation of new validator set with 0 fees", + delegator: sdk.AccAddress([]byte("addr3---------------")), + preferences: []types.ValidatorPreference{ + { + ValOperAddress: valAddrs[0], + Weight: sdk.NewDecWithPrec(5, 1), + }, + { + ValOperAddress: valAddrs[1], + Weight: sdk.NewDecWithPrec(5, 1), + }, + }, + creationFee: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(0))), + expectPass: false, + }, + } + + for _, test := range tests { + suite.Run(test.name, func() { + + bankKeeper := suite.App.BankKeeper + + // fund the account that is trying to delegate + suite.FundAcc(test.delegator, sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, 100)}) + initialBalance := bankKeeper.GetBalance(suite.Ctx, test.delegator, sdk.DefaultBondDenom).Amount + + // set the creation fee + suite.App.ValidatorPreferenceKeeper.SetParams(suite.Ctx, types.Params{ + ValsetCreationFee: test.creationFee, + }) + + // setup message server + msgServer := valPref.NewMsgServerImpl(suite.App.ValidatorPreferenceKeeper) + c := sdk.WrapSDKContext(suite.Ctx) + + // call the create validator set preference + _, err := msgServer.SetValidatorSetPreference(c, types.NewMsgSetValidatorSetPreference(test.delegator, test.preferences)) + if test.expectPass { + suite.Require().NoError(err) + + // check if the fee has been used + balance := bankKeeper.GetBalance(suite.Ctx, test.delegator, sdk.DefaultBondDenom).Amount + suite.Require().True(balance.LT(initialBalance)) + } else { + suite.Require().Error(err) + } + + }) + } +} diff --git a/x/validator-preference/types/codec.go b/x/validator-preference/types/codec.go new file mode 100644 index 00000000000..7ae94351939 --- /dev/null +++ b/x/validator-preference/types/codec.go @@ -0,0 +1,29 @@ +package types + +import ( + "github.com/cosmos/cosmos-sdk/codec" + cdctypes "github.com/cosmos/cosmos-sdk/codec/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/msgservice" +) + +func RegisterCodec(cdc *codec.LegacyAmino) { + cdc.RegisterConcrete(&MsgSetValidatorSetPreference{}, "", nil) + cdc.RegisterConcrete(&MsgDelegateToValidatorSet{}, "", nil) + cdc.RegisterConcrete(&MsgUndelegateFromValidatorSet{}, "", nil) +} + +func RegisterInterfaces(registry cdctypes.InterfaceRegistry) { + registry.RegisterImplementations((*sdk.Msg)(nil), + &MsgSetValidatorSetPreference{}, + &MsgDelegateToValidatorSet{}, + &MsgUndelegateFromValidatorSet{}, + ) + + msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc) +} + +var ( + Amino = codec.NewLegacyAmino() + ModuleCdc = codec.NewProtoCodec(cdctypes.NewInterfaceRegistry()) +) diff --git a/x/validator-preference/types/errors.go b/x/validator-preference/types/errors.go new file mode 100644 index 00000000000..ab1254f4c2b --- /dev/null +++ b/x/validator-preference/types/errors.go @@ -0,0 +1 @@ +package types diff --git a/x/validator-preference/types/expected_interfaces.go b/x/validator-preference/types/expected_interfaces.go new file mode 100644 index 00000000000..193cfd11b91 --- /dev/null +++ b/x/validator-preference/types/expected_interfaces.go @@ -0,0 +1,27 @@ +package types + +import ( + "time" + + sdk "github.com/cosmos/cosmos-sdk/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" +) + +// StakingInterface expected staking keeper. +type StakingInterface interface { + GetAllValidators(ctx sdk.Context) (validators []stakingtypes.Validator) + GetValidator(ctx sdk.Context, addr sdk.ValAddress) (validator stakingtypes.Validator, found bool) + Delegate(ctx sdk.Context, delAddr sdk.AccAddress, bondAmt sdk.Int, tokenSrc stakingtypes.BondStatus, validator stakingtypes.Validator, subtractAccount bool) (newShares sdk.Dec, err error) + GetDelegation(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) (delegation stakingtypes.Delegation, found bool) + Undelegate(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress, sharesAmount sdk.Dec) (time.Time, error) +} + +// BankInterface defines the expected interface needed to retrieve account balances. +type BankInterface interface { + GetAllBalances(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins +} + +// DistrInterface defines the contract needed to be fulfilled for community pool interactions. +type DistrInterface interface { + FundCommunityPool(ctx sdk.Context, amount sdk.Coins, sender sdk.AccAddress) error +} diff --git a/x/validator-preference/types/genesis.go b/x/validator-preference/types/genesis.go new file mode 100644 index 00000000000..9167936c6bb --- /dev/null +++ b/x/validator-preference/types/genesis.go @@ -0,0 +1,17 @@ +package types + +// DefaultGenesis creates a default GenesisState object. +func DefaultGenesis() *GenesisState { + return &GenesisState{ + Params: DefaultParams(), + } +} + +// Validate performs basic genesis state validation returning an error upon any +// failure. +func (gs GenesisState) Validate() error { + if err := gs.Params.Validate(); err != nil { + return err + } + return nil +} diff --git a/x/validator-preference/types/genesis.pb.go b/x/validator-preference/types/genesis.pb.go new file mode 100644 index 00000000000..2c8456291bf --- /dev/null +++ b/x/validator-preference/types/genesis.pb.go @@ -0,0 +1,321 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: osmosis/validator-preference/v1beta1/genesis.proto + +package types + +import ( + fmt "fmt" + _ "github.com/gogo/protobuf/gogoproto" + proto "github.com/gogo/protobuf/proto" + _ "google.golang.org/genproto/googleapis/api/annotations" + 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 + +// GenesisState defines the validator-set preference module's genesis state. +type GenesisState struct { + // params defines the paramaters of the module. + Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` +} + +func (m *GenesisState) Reset() { *m = GenesisState{} } +func (m *GenesisState) String() string { return proto.CompactTextString(m) } +func (*GenesisState) ProtoMessage() {} +func (*GenesisState) Descriptor() ([]byte, []int) { + return fileDescriptor_5b7bc6798806d1f2, []int{0} +} +func (m *GenesisState) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *GenesisState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_GenesisState.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 *GenesisState) XXX_Merge(src proto.Message) { + xxx_messageInfo_GenesisState.Merge(m, src) +} +func (m *GenesisState) XXX_Size() int { + return m.Size() +} +func (m *GenesisState) XXX_DiscardUnknown() { + xxx_messageInfo_GenesisState.DiscardUnknown(m) +} + +var xxx_messageInfo_GenesisState proto.InternalMessageInfo + +func init() { + proto.RegisterType((*GenesisState)(nil), "osmosis.validatorpreference.v1beta1.GenesisState") +} + +func init() { + proto.RegisterFile("osmosis/validator-preference/v1beta1/genesis.proto", fileDescriptor_5b7bc6798806d1f2) +} + +var fileDescriptor_5b7bc6798806d1f2 = []byte{ + // 251 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0xcf, 0xb1, 0x4a, 0xc4, 0x30, + 0x18, 0x07, 0xf0, 0x04, 0xe4, 0x86, 0xea, 0x74, 0x38, 0x48, 0x91, 0x28, 0xba, 0x08, 0x72, 0x09, + 0xad, 0x2f, 0x20, 0xb7, 0x88, 0x9b, 0xe8, 0xa4, 0x83, 0xf0, 0xf5, 0xfc, 0x8c, 0x81, 0x36, 0x5f, + 0x48, 0xe2, 0xa1, 0x6f, 0xe1, 0x63, 0x75, 0xbc, 0xd1, 0x49, 0xb4, 0x7d, 0x11, 0xb1, 0x0d, 0xe7, + 0x72, 0xc3, 0x6d, 0x81, 0xe4, 0xf7, 0xcf, 0xff, 0x9f, 0x95, 0x14, 0x1a, 0x0a, 0x26, 0xa8, 0x25, + 0xd4, 0xe6, 0x09, 0x22, 0xf9, 0x99, 0xf3, 0xf8, 0x8c, 0x1e, 0xed, 0x02, 0xd5, 0xb2, 0xa8, 0x30, + 0x42, 0xa1, 0x34, 0x5a, 0x0c, 0x26, 0x48, 0xe7, 0x29, 0xd2, 0xf4, 0x34, 0x19, 0xb9, 0x36, 0xff, + 0x44, 0x26, 0x92, 0xef, 0x6b, 0xd2, 0x34, 0xbc, 0x57, 0x7f, 0xa7, 0x91, 0xe6, 0x87, 0x9a, 0x48, + 0xd7, 0xa8, 0xc0, 0x19, 0x05, 0xd6, 0x52, 0x84, 0x68, 0xc8, 0xa6, 0xe0, 0xbc, 0xd8, 0xaa, 0x8c, + 0x03, 0x0f, 0x4d, 0x22, 0x27, 0xf7, 0xd9, 0xde, 0xd5, 0x58, 0xee, 0x2e, 0x42, 0xc4, 0xe9, 0x75, + 0x36, 0x19, 0xef, 0x0f, 0xf8, 0x31, 0x3f, 0xdb, 0x2d, 0xcf, 0xe5, 0x16, 0x65, 0xe5, 0xcd, 0x40, + 0xe6, 0x3b, 0xed, 0xd7, 0x11, 0xbb, 0x4d, 0x01, 0xf3, 0xc7, 0xf6, 0x47, 0xb0, 0xb6, 0x13, 0x7c, + 0xd5, 0x09, 0xfe, 0xdd, 0x09, 0xfe, 0xd1, 0x0b, 0xb6, 0xea, 0x05, 0xfb, 0xec, 0x05, 0x7b, 0xb8, + 0xd4, 0x26, 0xbe, 0xbc, 0x56, 0x72, 0x41, 0x8d, 0x4a, 0x5f, 0xcc, 0x6a, 0xa8, 0x82, 0x5a, 0x6f, + 0x28, 0x4a, 0xf5, 0xb6, 0x79, 0x49, 0x7c, 0x77, 0x18, 0xaa, 0xc9, 0xb0, 0xe0, 0xe2, 0x37, 0x00, + 0x00, 0xff, 0xff, 0x2a, 0xed, 0x9f, 0x7b, 0x83, 0x01, 0x00, 0x00, +} + +func (m *GenesisState) 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 *GenesisState) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Params.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func encodeVarintGenesis(dAtA []byte, offset int, v uint64) int { + offset -= sovGenesis(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *GenesisState) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Params.Size() + n += 1 + l + sovGenesis(uint64(l)) + return n +} + +func sovGenesis(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozGenesis(x uint64) (n int) { + return sovGenesis(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *GenesisState) 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 ErrIntOverflowGenesis + } + 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: GenesisState: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GenesisState: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenesis(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenesis + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipGenesis(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, ErrIntOverflowGenesis + } + 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, ErrIntOverflowGenesis + } + 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, ErrIntOverflowGenesis + } + 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, ErrInvalidLengthGenesis + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupGenesis + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthGenesis + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthGenesis = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowGenesis = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupGenesis = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/validator-preference/types/keys.go b/x/validator-preference/types/keys.go new file mode 100644 index 00000000000..494bd472783 --- /dev/null +++ b/x/validator-preference/types/keys.go @@ -0,0 +1,18 @@ +package types + +var ( + // ModuleName defines the module name + ModuleName = "validator-set-preference" + + // StoreKey defines the primary module store key + StoreKey = ModuleName + + // RouterKey is the message route for slashing. + RouterKey = ModuleName + + // KeyPrefixValidatorSet defines prefix key for validator set. + KeyPrefixValidatorSet = []byte{0x01} + + // QuerierRoute defines the module's query routing key + QuerierRoute = ModuleName +) diff --git a/x/validator-preference/types/msgs.go b/x/validator-preference/types/msgs.go new file mode 100644 index 00000000000..15e53f45e02 --- /dev/null +++ b/x/validator-preference/types/msgs.go @@ -0,0 +1,146 @@ +package types + +import ( + fmt "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/osmosis-labs/osmosis/v12/osmoutils" +) + +// constants +const ( + TypeMsgSetValidatorSetPreference = "set_validator_set_preference" +) + +var _ sdk.Msg = &MsgSetValidatorSetPreference{} + +// NewMsgCreateValidatorSetPreference creates a msg to create a validator-set preference. +func NewMsgSetValidatorSetPreference(delegator sdk.AccAddress, preferences []ValidatorPreference) *MsgSetValidatorSetPreference { + return &MsgSetValidatorSetPreference{ + Delegator: delegator.String(), + Preferences: preferences, + } +} + +func (m MsgSetValidatorSetPreference) Route() string { return RouterKey } +func (m MsgSetValidatorSetPreference) Type() string { return TypeMsgSetValidatorSetPreference } +func (m MsgSetValidatorSetPreference) ValidateBasic() error { + _, err := sdk.AccAddressFromBech32(m.Delegator) + if err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "Invalid delegator address (%s)", err) + } + + total_weight := sdk.NewDec(0) + validatorAddrs := []string{} + for _, validator := range m.Preferences { + _, err := sdk.ValAddressFromBech32(validator.ValOperAddress) + if err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "Invalid validator address (%s)", err) + } + + total_weight = total_weight.Add(validator.Weight) + validatorAddrs = append(validatorAddrs, validator.ValOperAddress) + } + + // check that all the validator address are unique + containsDuplicate := osmoutils.ContainsDuplicate(validatorAddrs) + if containsDuplicate { + return fmt.Errorf("The validator operator address are duplicated") + } + + // check if the total validator distribution weights equal 1 + if !total_weight.Equal(sdk.NewDec(1)) { + return fmt.Errorf("The weights allocated to the validators do not add up to 1, Got: %d", total_weight) + } + + return nil +} + +func (m MsgSetValidatorSetPreference) GetSignBytes() []byte { + return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&m)) +} + +// GetSigners takes a create validator-set message and returns the delegator in a byte array. +func (m MsgSetValidatorSetPreference) GetSigners() []sdk.AccAddress { + delegator, _ := sdk.AccAddressFromBech32(m.Delegator) + return []sdk.AccAddress{delegator} +} + +// constants +const ( + TypeMsgDelegateToValidatorSet = "delegate_to_validator_set" +) + +var _ sdk.Msg = &MsgDelegateToValidatorSet{} + +// NewMsgMsgStakeToValidatorSet creates a msg to stake to a validator set. +func NewMsgMsgStakeToValidatorSet(delegator sdk.AccAddress, coin sdk.Coin) *MsgDelegateToValidatorSet { + return &MsgDelegateToValidatorSet{ + Delegator: delegator.String(), + Coin: coin, + } +} + +func (m MsgDelegateToValidatorSet) Route() string { return RouterKey } +func (m MsgDelegateToValidatorSet) Type() string { return TypeMsgDelegateToValidatorSet } +func (m MsgDelegateToValidatorSet) ValidateBasic() error { + _, err := sdk.AccAddressFromBech32(m.Delegator) + if err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "Invalid sender address (%s)", err) + } + + if !m.Coin.IsValid() { + return fmt.Errorf("The stake coin is not valid") + } + + return nil +} + +func (m MsgDelegateToValidatorSet) GetSignBytes() []byte { + return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&m)) +} + +func (m MsgDelegateToValidatorSet) GetSigners() []sdk.AccAddress { + delegator, _ := sdk.AccAddressFromBech32(m.Delegator) + return []sdk.AccAddress{delegator} +} + +// constants +const ( + TypeMsgUndelegateFromValidatorSet = "undelegate_from_validator_set" +) + +var _ sdk.Msg = &MsgUndelegateFromValidatorSet{} + +// NewMsgMsgStakeToValidatorSet creates a msg to stake to a validator. +func NewMsgUndelegateFromValidatorSet(delegator sdk.AccAddress, coin sdk.Coin) *MsgUndelegateFromValidatorSet { + return &MsgUndelegateFromValidatorSet{ + Delegator: delegator.String(), + Coin: coin, + } +} + +func (m MsgUndelegateFromValidatorSet) Route() string { return RouterKey } +func (m MsgUndelegateFromValidatorSet) Type() string { return TypeMsgUndelegateFromValidatorSet } +func (m MsgUndelegateFromValidatorSet) ValidateBasic() error { + _, err := sdk.AccAddressFromBech32(m.Delegator) + if err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "Invalid sender address (%s)", err) + } + + if !m.Coin.IsValid() { + return fmt.Errorf("The stake coin is not valid") + } + + return nil +} + +func (m MsgUndelegateFromValidatorSet) GetSignBytes() []byte { + return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&m)) +} + +func (m MsgUndelegateFromValidatorSet) GetSigners() []sdk.AccAddress { + delegator, _ := sdk.AccAddressFromBech32(m.Delegator) + return []sdk.AccAddress{delegator} +} diff --git a/x/validator-preference/types/msgs_test.go b/x/validator-preference/types/msgs_test.go new file mode 100644 index 00000000000..3a02ed9ee16 --- /dev/null +++ b/x/validator-preference/types/msgs_test.go @@ -0,0 +1,133 @@ +package types_test + +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/require" + + "github.com/osmosis-labs/osmosis/v12/app/apptesting" + appParams "github.com/osmosis-labs/osmosis/v12/app/params" + "github.com/osmosis-labs/osmosis/v12/x/validator-preference/types" +) + +func TestMsgSetValidatorSetPreference(t *testing.T) { + appParams.SetAddressPrefixes() + addr1, invalidAddr := apptesting.GenerateTestAddrs() + + tests := []struct { + name string + msg types.MsgSetValidatorSetPreference + expectPass bool + }{ + { + name: "proper msg", + msg: types.MsgSetValidatorSetPreference{ + Delegator: addr1, + Preferences: []types.ValidatorPreference{ + { + ValOperAddress: "osmovaloper1x2cfenmflhj3dwm2ph6nkgqr3nppkg86fxaymg", + Weight: sdk.NewDecWithPrec(5, 1), + }, + { + ValOperAddress: "osmovaloper1jcr68jghzm24zwe78zuhz7xahua8429erxk7vm", + Weight: sdk.NewDecWithPrec(3, 1), + }, + { + ValOperAddress: "osmovaloper1gqsr38e4zteekwr6kq5se5jpadafqmcfyz8jds", + Weight: sdk.NewDecWithPrec(2, 1), + }, + }, + }, + expectPass: true, + }, + { + name: "duplicate validator msg", + msg: types.MsgSetValidatorSetPreference{ + Delegator: addr1, + Preferences: []types.ValidatorPreference{ + { + ValOperAddress: "osmovaloper1x2cfenmflhj3dwm2ph6nkgqr3nppkg86fxaymg", + Weight: sdk.NewDecWithPrec(6, 1), + }, + { + ValOperAddress: "osmovaloper1x2cfenmflhj3dwm2ph6nkgqr3nppkg86fxaymg", + Weight: sdk.NewDecWithPrec(4, 1), + }, + }, + }, + expectPass: false, + }, + { + name: "invalid delegator", + msg: types.MsgSetValidatorSetPreference{ + Delegator: invalidAddr, + Preferences: []types.ValidatorPreference{ + { + ValOperAddress: "osmovaloper1x2cfenmflhj3dwm2ph6nkgqr3nppkg86fxaymg", + Weight: sdk.NewDec(1), + }, + }, + }, + expectPass: false, + }, + { + name: "invalid validator address", + msg: types.MsgSetValidatorSetPreference{ + Delegator: addr1, + Preferences: []types.ValidatorPreference{ + { + ValOperAddress: "osmovaloper1x2cfenmflhj3dwm2ph6nkgqr3nppkg86fxay", // invalid address + Weight: sdk.NewDecWithPrec(2, 1), + }, + { + ValOperAddress: "osmovaloper1jcr68jghzm24zwe78zuhz7xahua8429erxk7vm", + Weight: sdk.NewDecWithPrec(2, 1), + }, + { + ValOperAddress: "osmovaloper1x2cfenmflhj3dwm2ph6nkgqr3nppkg86fxaymg", + Weight: sdk.NewDecWithPrec(6, 1), + }, + }, + }, + expectPass: false, + }, + { + name: "weights != 1", + msg: types.MsgSetValidatorSetPreference{ + Delegator: addr1, + Preferences: []types.ValidatorPreference{ + { + ValOperAddress: "osmovaloper1x2cfenmflhj3dwm2ph6nkgqr3nppkg86fxaymg", + Weight: sdk.NewDecWithPrec(5, 1), + }, + { + ValOperAddress: "osmovaloper1jcr68jghzm24zwe78zuhz7xahua8429erxk7vm", + Weight: sdk.NewDecWithPrec(3, 1), + }, + { + ValOperAddress: "osmovaloper1gqsr38e4zteekwr6kq5se5jpadafqmcfyz8jds", + Weight: sdk.NewDecWithPrec(3, 1), + }, + }, + }, + expectPass: false, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + if test.expectPass { + require.NoError(t, test.msg.ValidateBasic(), "test: %v", test.name) + require.Equal(t, test.msg.Route(), types.RouterKey) + require.Equal(t, test.msg.Type(), "set_validator_set_preference") + signers := test.msg.GetSigners() + require.Equal(t, len(signers), 1) + require.Equal(t, signers[0].String(), addr1) + } else { + require.Error(t, test.msg.ValidateBasic(), "test: %v", test.name) + } + }) + } + +} diff --git a/x/validator-preference/types/params.go b/x/validator-preference/types/params.go new file mode 100644 index 00000000000..792d51fae36 --- /dev/null +++ b/x/validator-preference/types/params.go @@ -0,0 +1,62 @@ +package types + +import ( + "fmt" + + appparams "github.com/osmosis-labs/osmosis/v12/app/params" + + sdk "github.com/cosmos/cosmos-sdk/types" + paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" +) + +// Parameter store keys. +var ( + KeyValSetCreationFee = []byte("ValSetCreationFee") +) + +// ParamTable for gamm module. +func ParamKeyTable() paramtypes.KeyTable { + return paramtypes.NewKeyTable().RegisterParamSet(&Params{}) +} + +func NewParams(valSetCreationFee sdk.Coins) Params { + return Params{ + ValsetCreationFee: valSetCreationFee, + } +} + +// default gamm module parameters. +func DefaultParams() Params { + return Params{ + ValsetCreationFee: sdk.NewCoins(sdk.NewInt64Coin(appparams.BaseCoinUnit, 10_000_000)), // 10 OSMO + } +} + +// validate params. +func (p Params) Validate() error { + if err := validateValSetCreationFee(p.ValsetCreationFee); err != nil { + return err + } + + return nil +} + +// Implements params.ParamSet. +func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs { + return paramtypes.ParamSetPairs{ + paramtypes.NewParamSetPair(KeyValSetCreationFee, &p.ValsetCreationFee, validateValSetCreationFee), + } +} + +func validateValSetCreationFee(i interface{}) error { + v, ok := i.(sdk.Coins) + if !ok { + return fmt.Errorf("invalid parameter type: %T", i) + } + + if v.Validate() != nil { + return fmt.Errorf("invalid val-set creation fee: %+v", i) + } + + return nil +} diff --git a/x/validator-preference/types/params.pb.go b/x/validator-preference/types/params.pb.go new file mode 100644 index 00000000000..462ca83e3f3 --- /dev/null +++ b/x/validator-preference/types/params.pb.go @@ -0,0 +1,341 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: osmosis/validator-preference/v1beta1/params.proto + +package types + +import ( + fmt "fmt" + _ "github.com/cosmos/cosmos-proto" + github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types" + types "github.com/cosmos/cosmos-sdk/types" + _ "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 + +// Params defines the parameters for the module. +type Params struct { + ValsetCreationFee github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,1,rep,name=valset_creation_fee,json=valsetCreationFee,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"valset_creation_fee" yaml:"valset_creation_fee"` +} + +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_db06f71db3b2b0f5, []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) GetValsetCreationFee() github_com_cosmos_cosmos_sdk_types.Coins { + if m != nil { + return m.ValsetCreationFee + } + return nil +} + +func init() { + proto.RegisterType((*Params)(nil), "osmosis.validatorpreference.v1beta1.Params") +} + +func init() { + proto.RegisterFile("osmosis/validator-preference/v1beta1/params.proto", fileDescriptor_db06f71db3b2b0f5) +} + +var fileDescriptor_db06f71db3b2b0f5 = []byte{ + // 296 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x91, 0xb1, 0x4e, 0xc3, 0x30, + 0x10, 0x86, 0x63, 0x21, 0x75, 0x28, 0x13, 0x85, 0x81, 0x66, 0x70, 0x50, 0x58, 0xba, 0xc4, 0x56, + 0xca, 0xc6, 0x84, 0x5a, 0x89, 0x11, 0x21, 0xc6, 0x2e, 0x91, 0x93, 0x5e, 0x83, 0x45, 0x12, 0x47, + 0xb6, 0x89, 0xe8, 0x5b, 0xb0, 0xb2, 0x33, 0xf1, 0x24, 0x1d, 0x3b, 0x32, 0x15, 0x94, 0xbc, 0x01, + 0x4f, 0x80, 0x6a, 0x9b, 0x96, 0xa1, 0x53, 0x72, 0x3a, 0x7f, 0xdf, 0xfd, 0xba, 0xeb, 0xc7, 0x42, + 0x95, 0x42, 0x71, 0x45, 0x1b, 0x56, 0xf0, 0x39, 0xd3, 0x42, 0x46, 0xb5, 0x84, 0x05, 0x48, 0xa8, + 0x32, 0xa0, 0x4d, 0x9c, 0x82, 0x66, 0x31, 0xad, 0x99, 0x64, 0xa5, 0x22, 0xb5, 0x14, 0x5a, 0x0c, + 0x2e, 0x1d, 0x42, 0x76, 0xc8, 0x9e, 0x20, 0x8e, 0xf0, 0xcf, 0x72, 0x91, 0x0b, 0xf3, 0x9e, 0x6e, + 0xff, 0x2c, 0xea, 0x0f, 0x33, 0xc3, 0x26, 0xb6, 0x61, 0x0b, 0xd7, 0xc2, 0xb6, 0xa2, 0x29, 0x53, + 0xfb, 0xb9, 0x99, 0xe0, 0x95, 0xed, 0x87, 0xef, 0xa8, 0xdf, 0xbb, 0x37, 0x31, 0x06, 0x6f, 0xa8, + 0x7f, 0xda, 0xb0, 0x42, 0x81, 0x4e, 0x32, 0x09, 0x4c, 0x73, 0x51, 0x25, 0x0b, 0x80, 0x73, 0x74, + 0x71, 0x34, 0x3a, 0x1e, 0x0f, 0x89, 0xf3, 0x6e, 0x4d, 0x7f, 0x79, 0xc8, 0x54, 0xf0, 0x6a, 0x72, + 0xb7, 0xda, 0x04, 0xde, 0xcf, 0x26, 0xf0, 0x97, 0xac, 0x2c, 0xae, 0xc3, 0x03, 0x8e, 0xf0, 0xe3, + 0x2b, 0x18, 0xe5, 0x5c, 0x3f, 0x3e, 0xa7, 0x24, 0x13, 0xa5, 0x8b, 0xe8, 0x3e, 0x91, 0x9a, 0x3f, + 0x51, 0xbd, 0xac, 0x41, 0x19, 0x9d, 0x7a, 0x38, 0xb1, 0x86, 0xa9, 0x13, 0xdc, 0x02, 0x4c, 0x66, + 0xab, 0x16, 0xa3, 0x75, 0x8b, 0xd1, 0x77, 0x8b, 0xd1, 0x6b, 0x87, 0xbd, 0x75, 0x87, 0xbd, 0xcf, + 0x0e, 0x7b, 0xb3, 0x9b, 0x7f, 0x5a, 0xb7, 0xc1, 0xa8, 0x60, 0xa9, 0xa2, 0xbb, 0x0b, 0xc4, 0x63, + 0xfa, 0x72, 0xf8, 0x0e, 0x66, 0x68, 0xda, 0x33, 0x9b, 0xb8, 0xfa, 0x0d, 0x00, 0x00, 0xff, 0xff, + 0x55, 0x97, 0x65, 0x82, 0xb4, 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.ValsetCreationFee) > 0 { + for iNdEx := len(m.ValsetCreationFee) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.ValsetCreationFee[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintParams(dAtA, i, uint64(size)) + } + 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.ValsetCreationFee) > 0 { + for _, e := range m.ValsetCreationFee { + l = e.Size() + 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 ValsetCreationFee", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthParams + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthParams + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ValsetCreationFee = append(m.ValsetCreationFee, types.Coin{}) + if err := m.ValsetCreationFee[len(m.ValsetCreationFee)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + 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") +) diff --git a/x/validator-preference/validator_set.go b/x/validator-preference/validator_set.go new file mode 100644 index 00000000000..d2c47675d5f --- /dev/null +++ b/x/validator-preference/validator_set.go @@ -0,0 +1,81 @@ +package keeper + +import ( + "fmt" + "sort" + + sdk "github.com/cosmos/cosmos-sdk/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + "github.com/osmosis-labs/osmosis/v12/x/validator-preference/types" +) + +// GetValAddrAndVal checks if the validator address is valid and the validator provided exists on chain. +func (k Keeper) getValAddrAndVal(ctx sdk.Context, valOperAddress string) (sdk.ValAddress, stakingtypes.Validator, error) { + valAddr, err := sdk.ValAddressFromBech32(valOperAddress) + if err != nil { + return nil, stakingtypes.Validator{}, fmt.Errorf("validator address not formatted") + } + + validator, found := k.stakingKeeper.GetValidator(ctx, valAddr) + if !found { + return nil, stakingtypes.Validator{}, fmt.Errorf("validator not found %s", validator) + } + + return valAddr, validator, nil +} + +// ValidatePreferences loops through the validator preferences and checks its existence and validity. +func (k Keeper) ValidatePreferences(ctx sdk.Context, preferences []types.ValidatorPreference) error { + for _, val := range preferences { + _, _, err := k.getValAddrAndVal(ctx, val.ValOperAddress) + if err != nil { + return err + } + } + return nil +} + +// ChargeForCreateValSet gets the creationFee (default 10osmo) and funds it to the community pool. +func (k Keeper) ChargeForCreateValSet(ctx sdk.Context, delegatorAddr string) error { + // Send creation fee to community pool + creationFee := k.GetParams(ctx).ValsetCreationFee + if creationFee == nil { + return fmt.Errorf("creation fee cannot be nil or 0 ") + } + + accAddr, err := sdk.AccAddressFromBech32(delegatorAddr) + if err != nil { + return err + } + + if err := k.distrKeeper.FundCommunityPool(ctx, creationFee, accAddr); err != nil { + return err + } + + return nil +} + +// SortAndCompareValidatorSet returns true if the two preferences are equal +func (k Keeper) SortAndCompareValidatorSet(newPreferences, existingPreferences []types.ValidatorPreference) bool { + if len(newPreferences) != len(existingPreferences) { + return false + } + + sort.Slice(newPreferences, func(i, j int) bool { + return newPreferences[i].ValOperAddress < newPreferences[j].ValOperAddress + }) + + sort.Slice(existingPreferences, func(i, j int) bool { + return existingPreferences[i].ValOperAddress < existingPreferences[j].ValOperAddress + }) + + // make sure that both valAddress and weights cannot be the same in the new val-set + for i := range newPreferences { + if newPreferences[i].ValOperAddress != existingPreferences[i].ValOperAddress || + !newPreferences[i].Weight.Equal(existingPreferences[i].Weight) { + return false + } + } + + return true +} diff --git a/x/validator-preference/valpref-module/module.go b/x/validator-preference/valpref-module/module.go new file mode 100644 index 00000000000..7e5a5171700 --- /dev/null +++ b/x/validator-preference/valpref-module/module.go @@ -0,0 +1,204 @@ +package validator_preference + +import ( + "encoding/json" + "fmt" + "math/rand" + + "github.com/gorilla/mux" + "github.com/grpc-ecosystem/grpc-gateway/runtime" + + keeper "github.com/osmosis-labs/osmosis/v12/x/validator-preference" + "github.com/osmosis-labs/osmosis/v12/x/validator-preference/types" + "github.com/spf13/cobra" + abci "github.com/tendermint/tendermint/abci/types" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/codec" + cdctypes "github.com/cosmos/cosmos-sdk/codec/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" + simtypes "github.com/cosmos/cosmos-sdk/types/simulation" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" +) + +var ( + _ module.AppModule = AppModule{} + _ module.AppModuleBasic = AppModuleBasic{} +) + +// ---------------------------------------------------------------------------- +// AppModuleBasic +// ---------------------------------------------------------------------------- + +// AppModuleBasic implements the AppModuleBasic interface for the capability module. +type AppModuleBasic struct { + cdc codec.Codec +} + +func NewAppModuleBasic(cdc codec.Codec) AppModuleBasic { + return AppModuleBasic{cdc: cdc} +} + +// Name returns the capability module's name. +func (AppModuleBasic) Name() string { + return types.ModuleName +} + +func (AppModuleBasic) RegisterCodec(cdc *codec.LegacyAmino) { + types.RegisterCodec(cdc) +} + +func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { + types.RegisterCodec(cdc) +} + +// RegisterInterfaces registers the module's interface types. +func (a AppModuleBasic) RegisterInterfaces(reg cdctypes.InterfaceRegistry) { + types.RegisterInterfaces(reg) +} + +// DefaultGenesis returns the capability module's default genesis state. +func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage { + return cdc.MustMarshalJSON(types.DefaultGenesis()) +} + +// ValidateGenesis performs genesis state validation for the capability module. +func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, config client.TxEncodingConfig, bz json.RawMessage) error { + var genState types.GenesisState + if err := cdc.UnmarshalJSON(bz, &genState); err != nil { + return fmt.Errorf("failed to unmarshal %s genesis state: %w", types.ModuleName, err) + } + return nil +} + +// RegisterRESTRoutes registers the capability module's REST service handlers. +func (AppModuleBasic) RegisterRESTRoutes(clientCtx client.Context, rtr *mux.Router) { +} + +// RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the module. +func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) { +} + +// GetTxCmd returns the capability module's root tx command. +func (a AppModuleBasic) GetTxCmd() *cobra.Command { + return nil +} + +// GetQueryCmd returns the capability module's root query command. +func (AppModuleBasic) GetQueryCmd() *cobra.Command { + return nil +} + +// ---------------------------------------------------------------------------- +// AppModule +// ---------------------------------------------------------------------------- + +// AppModule implements the AppModule interface for the capability module. +type AppModule struct { + AppModuleBasic + + keeper keeper.Keeper + accountKeeper stakingtypes.AccountKeeper + bankKeeper stakingtypes.BankKeeper +} + +func NewAppModule(cdc codec.Codec, keeper keeper.Keeper, + accountKeeper stakingtypes.AccountKeeper, + bankKeeper stakingtypes.BankKeeper, +) AppModule { + return AppModule{ + AppModuleBasic: NewAppModuleBasic(cdc), + keeper: keeper, + + accountKeeper: accountKeeper, + bankKeeper: bankKeeper, + } +} + +// Name returns the capability module's name. +func (am AppModule) Name() string { + return am.AppModuleBasic.Name() +} + +// Route returns the capability module's message routing key. +func (am AppModule) Route() sdk.Route { + return sdk.Route{} +} + +// QuerierRoute returns the capability module's query routing key. +func (AppModule) QuerierRoute() string { return types.QuerierRoute } + +// LegacyQuerierHandler returns the x/validator-preference module's Querier. +func (am AppModule) LegacyQuerierHandler(legacyQuerierCdc *codec.LegacyAmino) sdk.Querier { + return func(sdk.Context, []string, abci.RequestQuery) ([]byte, error) { + return nil, fmt.Errorf("legacy querier not supported for the x/%s module", types.ModuleName) + } +} + +// RegisterServices registers module services. +func (am AppModule) RegisterServices(cfg module.Configurator) { +} + +// RegisterInvariants registers the capability module's invariants. +func (am AppModule) RegisterInvariants(ir sdk.InvariantRegistry) { +} + +// InitGenesis performs the capability module's genesis initialization It returns +// no validator updates. +// TODO: implement this +func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, gs json.RawMessage) []abci.ValidatorUpdate { + var genState types.GenesisState + // Initialize global index to index in genesis state + cdc.MustUnmarshalJSON(gs, &genState) + am.keeper.InitGenesis(ctx, genState) + return []abci.ValidatorUpdate{} +} + +// ExportGenesis returns the capability module's exported genesis state as raw JSON bytes. +// TODO: Come back and fix this +func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawMessage { + genState := am.keeper.ExportGenesis(ctx) + return cdc.MustMarshalJSON(genState) +} + +// BeginBlock executes all ABCI BeginBlock logic respective to the capability module. +func (am AppModule) BeginBlock(ctx sdk.Context, _ abci.RequestBeginBlock) {} + +// EndBlock executes all ABCI EndBlock logic respective to the capability module. It +// returns no validator updates. +func (am AppModule) EndBlock(ctx sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate { + return []abci.ValidatorUpdate{} +} + +// ___________________________________________________________________________ + +// AppModuleSimulation functions + +// GenerateGenesisState creates a randomized GenState of the pool-incentives module. +func (AppModule) GenerateGenesisState(simState *module.SimulationState) { +} + +// ProposalContents doesn't return any content functions for governance proposals. +func (am AppModule) ProposalContents(simState module.SimulationState) []simtypes.WeightedProposalContent { + return []simtypes.WeightedProposalContent{} +} + +// RandomizedParams creates randomized pool-incentives param changes for the simulator. +func (AppModule) RandomizedParams(r *rand.Rand) []simtypes.ParamChange { + return nil // TODO +} + +// RegisterStoreDecoder registers a decoder for supply module's types. +func (am AppModule) RegisterStoreDecoder(sdr sdk.StoreDecoderRegistry) { + // TODO +} + +// WeightedOperations returns the all the module operations with their respective weights. +func (am AppModule) WeightedOperations(simState module.SimulationState) []simtypes.WeightedOperation { + return []simtypes.WeightedOperation{} +} + +func (am AppModule) ConsensusVersion() uint64 { + return 1 +} From 892ae0067499e716f04534a01e5210d8346c87b8 Mon Sep 17 00:00:00 2001 From: stackman27 Date: Thu, 13 Oct 2022 01:06:45 -0700 Subject: [PATCH 2/3] [ValSet-Pref] Module Wired up and created MsgSetValidatorSetPreference --- app/keepers/keepers.go | 63 ++-- app/keepers/modules.go | 2 + app/modules.go | 5 + app/upgrades/v13/constants.go | 11 +- osmoutils/slice_helper.go | 4 +- .../v1beta1/genesis.proto | 15 - .../validator-preference/v1beta1/params.proto | 17 - .../v1beta1/query.proto | 11 +- .../v1beta1/state.proto | 4 +- .../v1beta1/tx.proto | 8 +- tests/e2e/scripts/rate_limiter.wasm | Bin 185356 -> 203516 bytes x/validator-preference/genesis.go | 20 - x/validator-preference/types/errors.go | 1 - x/validator-preference/types/genesis.go | 17 - x/validator-preference/types/genesis.pb.go | 321 ----------------- x/validator-preference/types/params.go | 62 ---- x/validator-preference/types/params.pb.go | 341 ------------------ .../README.md | 0 x/valset-pref/client/query_proto_wrap.go | 22 ++ .../client/queryproto/query.pb.go | 82 ++--- .../client/queryproto/query.pb.gw.go | 20 +- .../keeper.go | 36 +- .../keeper_test.go | 2 +- .../msg_server.go | 26 +- .../msg_server_test.go | 86 ++--- .../types/codec.go | 8 +- .../types/expected_interfaces.go | 10 - .../types/keys.go | 2 +- .../types/msgs.go | 34 ++ .../types/msgs_test.go | 29 +- .../types/state.pb.go | 62 ++-- .../types/tx.pb.go | 124 +++---- .../validator_set.go | 66 ++-- .../valpref-module/module.go | 43 +-- 34 files changed, 394 insertions(+), 1160 deletions(-) delete mode 100644 proto/osmosis/validator-preference/v1beta1/genesis.proto delete mode 100644 proto/osmosis/validator-preference/v1beta1/params.proto rename proto/osmosis/{validator-preference => valset-pref}/v1beta1/query.proto (68%) rename proto/osmosis/{validator-preference => valset-pref}/v1beta1/state.proto (90%) rename proto/osmosis/{validator-preference => valset-pref}/v1beta1/tx.proto (92%) delete mode 100644 x/validator-preference/genesis.go delete mode 100644 x/validator-preference/types/errors.go delete mode 100644 x/validator-preference/types/genesis.go delete mode 100644 x/validator-preference/types/genesis.pb.go delete mode 100644 x/validator-preference/types/params.go delete mode 100644 x/validator-preference/types/params.pb.go rename x/{validator-preference => valset-pref}/README.md (100%) create mode 100644 x/valset-pref/client/query_proto_wrap.go rename x/{validator-preference => valset-pref}/client/queryproto/query.pb.go (81%) rename x/{validator-preference => valset-pref}/client/queryproto/query.pb.gw.go (92%) rename x/{validator-preference => valset-pref}/keeper.go (58%) rename x/{validator-preference => valset-pref}/keeper_test.go (94%) rename x/{validator-preference => valset-pref}/msg_server.go (62%) rename x/{validator-preference => valset-pref}/msg_server_test.go (55%) rename x/{validator-preference => valset-pref}/types/codec.go (55%) rename x/{validator-preference => valset-pref}/types/expected_interfaces.go (67%) rename x/{validator-preference => valset-pref}/types/keys.go (90%) rename x/{validator-preference => valset-pref}/types/msgs.go (81%) rename x/{validator-preference => valset-pref}/types/msgs_test.go (81%) rename x/{validator-preference => valset-pref}/types/state.pb.go (82%) rename x/{validator-preference => valset-pref}/types/tx.pb.go (89%) rename x/{validator-preference => valset-pref}/validator_set.go (51%) rename x/{validator-preference => valset-pref}/valpref-module/module.go (83%) diff --git a/app/keepers/keepers.go b/app/keepers/keepers.go index ab7d8fd1ca0..1090638c445 100644 --- a/app/keepers/keepers.go +++ b/app/keepers/keepers.go @@ -75,8 +75,8 @@ import ( "github.com/osmosis-labs/osmosis/v12/x/txfees" txfeeskeeper "github.com/osmosis-labs/osmosis/v12/x/txfees/keeper" txfeestypes "github.com/osmosis-labs/osmosis/v12/x/txfees/types" - validatorpreference "github.com/osmosis-labs/osmosis/v12/x/validator-preference" - validatorpreferencetypes "github.com/osmosis-labs/osmosis/v12/x/validator-preference/types" + valsetpref "github.com/osmosis-labs/osmosis/v12/x/valset-pref" + valsetpreftypes "github.com/osmosis-labs/osmosis/v12/x/valset-pref/types" ) type AppKeepers struct { @@ -94,29 +94,30 @@ type AppKeepers struct { ScopedWasmKeeper capabilitykeeper.ScopedKeeper // "Normal" keepers - AccountKeeper *authkeeper.AccountKeeper - BankKeeper *bankkeeper.BaseKeeper - AuthzKeeper *authzkeeper.Keeper - StakingKeeper *stakingkeeper.Keeper - DistrKeeper *distrkeeper.Keeper - SlashingKeeper *slashingkeeper.Keeper - IBCKeeper *ibckeeper.Keeper - ICAHostKeeper *icahostkeeper.Keeper - TransferKeeper *ibctransferkeeper.Keeper - EvidenceKeeper *evidencekeeper.Keeper - GAMMKeeper *gammkeeper.Keeper - TwapKeeper *twap.Keeper - LockupKeeper *lockupkeeper.Keeper - EpochsKeeper *epochskeeper.Keeper - IncentivesKeeper *incentiveskeeper.Keeper - MintKeeper *mintkeeper.Keeper - PoolIncentivesKeeper *poolincentiveskeeper.Keeper - TxFeesKeeper *txfeeskeeper.Keeper - SuperfluidKeeper *superfluidkeeper.Keeper - GovKeeper *govkeeper.Keeper - WasmKeeper *wasm.Keeper - ContractKeeper *wasmkeeper.PermissionedKeeper - TokenFactoryKeeper *tokenfactorykeeper.Keeper + AccountKeeper *authkeeper.AccountKeeper + BankKeeper *bankkeeper.BaseKeeper + AuthzKeeper *authzkeeper.Keeper + StakingKeeper *stakingkeeper.Keeper + DistrKeeper *distrkeeper.Keeper + SlashingKeeper *slashingkeeper.Keeper + IBCKeeper *ibckeeper.Keeper + ICAHostKeeper *icahostkeeper.Keeper + TransferKeeper *ibctransferkeeper.Keeper + EvidenceKeeper *evidencekeeper.Keeper + GAMMKeeper *gammkeeper.Keeper + TwapKeeper *twap.Keeper + LockupKeeper *lockupkeeper.Keeper + EpochsKeeper *epochskeeper.Keeper + IncentivesKeeper *incentiveskeeper.Keeper + MintKeeper *mintkeeper.Keeper + PoolIncentivesKeeper *poolincentiveskeeper.Keeper + TxFeesKeeper *txfeeskeeper.Keeper + SuperfluidKeeper *superfluidkeeper.Keeper + GovKeeper *govkeeper.Keeper + WasmKeeper *wasm.Keeper + ContractKeeper *wasmkeeper.PermissionedKeeper + TokenFactoryKeeper *tokenfactorykeeper.Keeper + ValidatorSetPreferenceKeeper *valsetpref.Keeper // IBC modules // transfer module @@ -340,15 +341,13 @@ func (appKeepers *AppKeepers) InitNormalKeepers( ) appKeepers.TokenFactoryKeeper = &tokenFactoryKeeper - validatorPreferenceKeeper := validatorpreference.NewKeeper( - appKeepers.keys[validatorpreferencetypes.StoreKey], - appKeepers.GetSubspace(validatorpreferencetypes.ModuleName), + validatorSetPreferenceKeeper := valsetpref.NewKeeper( + appKeepers.keys[valsetpreftypes.StoreKey], + appKeepers.GetSubspace(valsetpreftypes.ModuleName), appKeepers.StakingKeeper, - appKeepers.BankKeeper, - appKeepers.DistrKeeper, ) - appKeepers.ValidatorPreferenceKeeper = &validatorPreferenceKeeper + appKeepers.ValidatorSetPreferenceKeeper = &validatorSetPreferenceKeeper // The last arguments can contain custom message handlers, and custom query handlers, // if we want to allow any custom callbacks @@ -568,6 +567,6 @@ func KVStoreKeys() []string { superfluidtypes.StoreKey, wasm.StoreKey, tokenfactorytypes.StoreKey, - validatorpreferencetypes.StoreKey, + valsetpreftypes.StoreKey, } } diff --git a/app/keepers/modules.go b/app/keepers/modules.go index 88f214644c7..a24fccd4e97 100644 --- a/app/keepers/modules.go +++ b/app/keepers/modules.go @@ -40,6 +40,7 @@ import ( "github.com/osmosis-labs/osmosis/v12/x/tokenfactory" "github.com/osmosis-labs/osmosis/v12/x/twap/twapmodule" "github.com/osmosis-labs/osmosis/v12/x/txfees" + valsetprefmodule "github.com/osmosis-labs/osmosis/v12/x/valset-pref/valpref-module" ) // AppModuleBasics returns ModuleBasics for the module BasicManager. @@ -84,6 +85,7 @@ var AppModuleBasics = []module.AppModuleBasic{ epochs.AppModuleBasic{}, superfluid.AppModuleBasic{}, tokenfactory.AppModuleBasic{}, + valsetprefmodule.AppModuleBasic{}, wasm.AppModuleBasic{}, ica.AppModuleBasic{}, } diff --git a/app/modules.go b/app/modules.go index 3421fec2ba9..8c9ed5eb1cf 100644 --- a/app/modules.go +++ b/app/modules.go @@ -67,6 +67,8 @@ import ( twaptypes "github.com/osmosis-labs/osmosis/v12/x/twap/types" "github.com/osmosis-labs/osmosis/v12/x/txfees" txfeestypes "github.com/osmosis-labs/osmosis/v12/x/txfees/types" + valsetpreftypes "github.com/osmosis-labs/osmosis/v12/x/valset-pref/types" + valsetprefmodule "github.com/osmosis-labs/osmosis/v12/x/valset-pref/valpref-module" ) // moduleAccountPermissions defines module account permissions @@ -90,6 +92,7 @@ var moduleAccountPermissions = map[string][]string{ txfeestypes.NonNativeFeeCollectorName: nil, wasm.ModuleName: {authtypes.Burner}, tokenfactorytypes.ModuleName: {authtypes.Minter, authtypes.Burner}, + valsetpreftypes.ModuleName: {authtypes.Staking}, } // appModules return modules to initialize module manager. @@ -142,6 +145,7 @@ func appModules( app.EpochsKeeper, ), tokenfactory.NewAppModule(*app.TokenFactoryKeeper, app.AccountKeeper, app.BankKeeper), + valsetprefmodule.NewAppModule(appCodec, *app.ValidatorSetPreferenceKeeper), } } @@ -211,6 +215,7 @@ func OrderInitGenesis(allModuleNames []string) []string { poolincentivestypes.ModuleName, superfluidtypes.ModuleName, tokenfactorytypes.ModuleName, + valsetpreftypes.ModuleName, incentivestypes.ModuleName, epochstypes.ModuleName, lockuptypes.ModuleName, diff --git a/app/upgrades/v13/constants.go b/app/upgrades/v13/constants.go index 7779df096f6..cd42ff4813a 100644 --- a/app/upgrades/v13/constants.go +++ b/app/upgrades/v13/constants.go @@ -1,16 +1,19 @@ package v13 import ( - "github.com/osmosis-labs/osmosis/v12/app/upgrades" - store "github.com/cosmos/cosmos-sdk/store/types" + "github.com/osmosis-labs/osmosis/v12/app/upgrades" + valsetpreftypes "github.com/osmosis-labs/osmosis/v12/x/valset-pref/types" ) -// UpgradeName defines the on-chain upgrade name for the Osmosis v9 upgrade. +// UpgradeName defines the on-chain upgrade name for the Osmosis v13 upgrade. const UpgradeName = "v13" var Upgrade = upgrades.Upgrade{ UpgradeName: UpgradeName, CreateUpgradeHandler: CreateUpgradeHandler, - StoreUpgrades: store.StoreUpgrades{}, + StoreUpgrades: store.StoreUpgrades{ + Added: []string{valsetpreftypes.StoreKey}, + Deleted: []string{}, // double check bech32ibc + }, } diff --git a/osmoutils/slice_helper.go b/osmoutils/slice_helper.go index 913eb1c7254..a7ee4db4eb0 100644 --- a/osmoutils/slice_helper.go +++ b/osmoutils/slice_helper.go @@ -4,7 +4,6 @@ import ( "sort" "golang.org/x/exp/constraints" - ) // SortSlice sorts a slice of type T elements that implement constraints.Ordered. @@ -37,7 +36,7 @@ func ReverseSlice[T any](s []T) []T { return s } -// ContainsDuplicate checks if there are any duplicate +// ContainsDuplicate checks if there are any duplicate // elements in the slice. func ContainsDuplicate[T any](arr []T) bool { visited := make(map[any]bool, 0) @@ -50,4 +49,3 @@ func ContainsDuplicate[T any](arr []T) bool { } return false } - diff --git a/proto/osmosis/validator-preference/v1beta1/genesis.proto b/proto/osmosis/validator-preference/v1beta1/genesis.proto deleted file mode 100644 index 47d11cb652c..00000000000 --- a/proto/osmosis/validator-preference/v1beta1/genesis.proto +++ /dev/null @@ -1,15 +0,0 @@ -syntax = "proto3"; -package osmosis.validatorpreference.v1beta1; - -import "gogoproto/gogo.proto"; -import "google/api/annotations.proto"; -import "osmosis/validator-preference/v1beta1/params.proto"; - -option go_package = "github.com/osmosis-labs/osmosis/v12/x/validator-preference/types"; -option (gogoproto.goproto_getters_all) = false; - -// GenesisState defines the validator-set preference module's genesis state. -message GenesisState { - // params defines the paramaters of the module. - Params params = 1 [ (gogoproto.nullable) = false ]; -} diff --git a/proto/osmosis/validator-preference/v1beta1/params.proto b/proto/osmosis/validator-preference/v1beta1/params.proto deleted file mode 100644 index 454c99b24ad..00000000000 --- a/proto/osmosis/validator-preference/v1beta1/params.proto +++ /dev/null @@ -1,17 +0,0 @@ -syntax = "proto3"; -package osmosis.validatorpreference.v1beta1; - -import "gogoproto/gogo.proto"; -import "cosmos_proto/cosmos.proto"; -import "cosmos/base/v1beta1/coin.proto"; - -option go_package = "github.com/osmosis-labs/osmosis/v12/x/validator-preference/types"; - -// Params defines the parameters for the module. -message Params { - repeated cosmos.base.v1beta1.Coin valset_creation_fee = 1 [ - (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", - (gogoproto.moretags) = "yaml:\"valset_creation_fee\"", - (gogoproto.nullable) = false - ]; -} diff --git a/proto/osmosis/validator-preference/v1beta1/query.proto b/proto/osmosis/valset-pref/v1beta1/query.proto similarity index 68% rename from proto/osmosis/validator-preference/v1beta1/query.proto rename to proto/osmosis/valset-pref/v1beta1/query.proto index 9a6d666c8e4..e2ed5a54ac8 100644 --- a/proto/osmosis/validator-preference/v1beta1/query.proto +++ b/proto/osmosis/valset-pref/v1beta1/query.proto @@ -1,11 +1,11 @@ syntax = "proto3"; -package osmosis.validatorpreference.v1beta1; +package osmosis.valsetpref.v1beta1; import "gogoproto/gogo.proto"; import "google/api/annotations.proto"; -import "osmosis/validator-preference/v1beta1/state.proto"; +import "osmosis/valset-pref/v1beta1/state.proto"; -option go_package = "github.com/osmosis-labs/osmosis/v12/x/validator-preference/client/queryproto"; +option go_package = "github.com/osmosis-labs/osmosis/v12/x/valset-pref/client/queryproto"; option (gogoproto.goproto_getters_all) = false; // Query defines the gRPC querier service. @@ -13,15 +13,14 @@ service Query { // Returns the list of ValidatorPreferences for the user. rpc UserValidatorPreferences(QueryUserValidatorPreferences) returns (QueryUserValidatorPreferenceResponse) { - option (google.api.http).get = - "/osmosis/validator-preference/v1beta1/{user}"; + option (google.api.http).get = "/osmosis/valset-pref/v1beta1/{address}"; } } // Request type for UserValidatorPreferences. message QueryUserValidatorPreferences { // user account address - string user = 1; + string address = 1; } // Response type the QueryUserValidatorPreferences query request diff --git a/proto/osmosis/validator-preference/v1beta1/state.proto b/proto/osmosis/valset-pref/v1beta1/state.proto similarity index 90% rename from proto/osmosis/validator-preference/v1beta1/state.proto rename to proto/osmosis/valset-pref/v1beta1/state.proto index cbfcf56a34d..3b1ee283714 100644 --- a/proto/osmosis/validator-preference/v1beta1/state.proto +++ b/proto/osmosis/valset-pref/v1beta1/state.proto @@ -1,10 +1,10 @@ syntax = "proto3"; -package osmosis.validatorpreference.v1beta1; +package osmosis.valsetpref.v1beta1; import "gogoproto/gogo.proto"; import "google/api/annotations.proto"; -option go_package = "github.com/osmosis-labs/osmosis/v12/x/validator-preference/types"; +option go_package = "github.com/osmosis-labs/osmosis/v12/x/valset-pref/types"; option (gogoproto.goproto_getters_all) = false; // ValidatorPreference defines the message structure for diff --git a/proto/osmosis/validator-preference/v1beta1/tx.proto b/proto/osmosis/valset-pref/v1beta1/tx.proto similarity index 92% rename from proto/osmosis/validator-preference/v1beta1/tx.proto rename to proto/osmosis/valset-pref/v1beta1/tx.proto index 00967e38c9a..e0ef71fdcfd 100644 --- a/proto/osmosis/validator-preference/v1beta1/tx.proto +++ b/proto/osmosis/valset-pref/v1beta1/tx.proto @@ -1,13 +1,13 @@ syntax = "proto3"; -package osmosis.validatorpreference.v1beta1; +package osmosis.valsetpref.v1beta1; import "gogoproto/gogo.proto"; import "cosmos/base/v1beta1/coin.proto"; -import "osmosis/validator-preference/v1beta1/state.proto"; +import "osmosis/valset-pref/v1beta1/state.proto"; -option go_package = "github.com/osmosis-labs/osmosis/v12/x/validator-preference/types"; +option go_package = "github.com/osmosis-labs/osmosis/v12/x/valset-pref/types"; -// Msg defines the validator-preference modules's gRPC message service. +// Msg defines the valset-pref modules's gRPC message service. service Msg { // SetValidatorSetPreference creates a set of validator preference. // This message will process both create + update request. diff --git a/tests/e2e/scripts/rate_limiter.wasm b/tests/e2e/scripts/rate_limiter.wasm index f3f763f30a4ab739621979985532d401dd373fd7..e19651209c4009fd4bd73bae23f49c69424e91d3 100755 GIT binary patch literal 203516 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

w88I?#W&Qep@T#G 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 N`E_V*$&WSR{{|g7Reb;e diff --git a/x/validator-preference/genesis.go b/x/validator-preference/genesis.go deleted file mode 100644 index 375735b7ee0..00000000000 --- a/x/validator-preference/genesis.go +++ /dev/null @@ -1,20 +0,0 @@ -package keeper - -import ( - "github.com/osmosis-labs/osmosis/v12/x/validator-preference/types" - - sdk "github.com/cosmos/cosmos-sdk/types" -) - -// InitGenesis initializes the capability module's state from a provided genesis -// state. -func (k Keeper) InitGenesis(ctx sdk.Context, genState types.GenesisState) { - k.SetParams(ctx, genState.Params) -} - -// ExportGenesis returns the capability module's exported genesis. -func (k Keeper) ExportGenesis(ctx sdk.Context) *types.GenesisState { - return &types.GenesisState{ - Params: k.GetParams(ctx), - } -} diff --git a/x/validator-preference/types/errors.go b/x/validator-preference/types/errors.go deleted file mode 100644 index ab1254f4c2b..00000000000 --- a/x/validator-preference/types/errors.go +++ /dev/null @@ -1 +0,0 @@ -package types diff --git a/x/validator-preference/types/genesis.go b/x/validator-preference/types/genesis.go deleted file mode 100644 index 9167936c6bb..00000000000 --- a/x/validator-preference/types/genesis.go +++ /dev/null @@ -1,17 +0,0 @@ -package types - -// DefaultGenesis creates a default GenesisState object. -func DefaultGenesis() *GenesisState { - return &GenesisState{ - Params: DefaultParams(), - } -} - -// Validate performs basic genesis state validation returning an error upon any -// failure. -func (gs GenesisState) Validate() error { - if err := gs.Params.Validate(); err != nil { - return err - } - return nil -} diff --git a/x/validator-preference/types/genesis.pb.go b/x/validator-preference/types/genesis.pb.go deleted file mode 100644 index 2c8456291bf..00000000000 --- a/x/validator-preference/types/genesis.pb.go +++ /dev/null @@ -1,321 +0,0 @@ -// Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: osmosis/validator-preference/v1beta1/genesis.proto - -package types - -import ( - fmt "fmt" - _ "github.com/gogo/protobuf/gogoproto" - proto "github.com/gogo/protobuf/proto" - _ "google.golang.org/genproto/googleapis/api/annotations" - 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 - -// GenesisState defines the validator-set preference module's genesis state. -type GenesisState struct { - // params defines the paramaters of the module. - Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` -} - -func (m *GenesisState) Reset() { *m = GenesisState{} } -func (m *GenesisState) String() string { return proto.CompactTextString(m) } -func (*GenesisState) ProtoMessage() {} -func (*GenesisState) Descriptor() ([]byte, []int) { - return fileDescriptor_5b7bc6798806d1f2, []int{0} -} -func (m *GenesisState) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *GenesisState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_GenesisState.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 *GenesisState) XXX_Merge(src proto.Message) { - xxx_messageInfo_GenesisState.Merge(m, src) -} -func (m *GenesisState) XXX_Size() int { - return m.Size() -} -func (m *GenesisState) XXX_DiscardUnknown() { - xxx_messageInfo_GenesisState.DiscardUnknown(m) -} - -var xxx_messageInfo_GenesisState proto.InternalMessageInfo - -func init() { - proto.RegisterType((*GenesisState)(nil), "osmosis.validatorpreference.v1beta1.GenesisState") -} - -func init() { - proto.RegisterFile("osmosis/validator-preference/v1beta1/genesis.proto", fileDescriptor_5b7bc6798806d1f2) -} - -var fileDescriptor_5b7bc6798806d1f2 = []byte{ - // 251 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0xcf, 0xb1, 0x4a, 0xc4, 0x30, - 0x18, 0x07, 0xf0, 0x04, 0xe4, 0x86, 0xea, 0x74, 0x38, 0x48, 0x91, 0x28, 0xba, 0x08, 0x72, 0x09, - 0xad, 0x2f, 0x20, 0xb7, 0x88, 0x9b, 0xe8, 0xa4, 0x83, 0xf0, 0xf5, 0xfc, 0x8c, 0x81, 0x36, 0x5f, - 0x48, 0xe2, 0xa1, 0x6f, 0xe1, 0x63, 0x75, 0xbc, 0xd1, 0x49, 0xb4, 0x7d, 0x11, 0xb1, 0x0d, 0xe7, - 0x72, 0xc3, 0x6d, 0x81, 0xe4, 0xf7, 0xcf, 0xff, 0x9f, 0x95, 0x14, 0x1a, 0x0a, 0x26, 0xa8, 0x25, - 0xd4, 0xe6, 0x09, 0x22, 0xf9, 0x99, 0xf3, 0xf8, 0x8c, 0x1e, 0xed, 0x02, 0xd5, 0xb2, 0xa8, 0x30, - 0x42, 0xa1, 0x34, 0x5a, 0x0c, 0x26, 0x48, 0xe7, 0x29, 0xd2, 0xf4, 0x34, 0x19, 0xb9, 0x36, 0xff, - 0x44, 0x26, 0x92, 0xef, 0x6b, 0xd2, 0x34, 0xbc, 0x57, 0x7f, 0xa7, 0x91, 0xe6, 0x87, 0x9a, 0x48, - 0xd7, 0xa8, 0xc0, 0x19, 0x05, 0xd6, 0x52, 0x84, 0x68, 0xc8, 0xa6, 0xe0, 0xbc, 0xd8, 0xaa, 0x8c, - 0x03, 0x0f, 0x4d, 0x22, 0x27, 0xf7, 0xd9, 0xde, 0xd5, 0x58, 0xee, 0x2e, 0x42, 0xc4, 0xe9, 0x75, - 0x36, 0x19, 0xef, 0x0f, 0xf8, 0x31, 0x3f, 0xdb, 0x2d, 0xcf, 0xe5, 0x16, 0x65, 0xe5, 0xcd, 0x40, - 0xe6, 0x3b, 0xed, 0xd7, 0x11, 0xbb, 0x4d, 0x01, 0xf3, 0xc7, 0xf6, 0x47, 0xb0, 0xb6, 0x13, 0x7c, - 0xd5, 0x09, 0xfe, 0xdd, 0x09, 0xfe, 0xd1, 0x0b, 0xb6, 0xea, 0x05, 0xfb, 0xec, 0x05, 0x7b, 0xb8, - 0xd4, 0x26, 0xbe, 0xbc, 0x56, 0x72, 0x41, 0x8d, 0x4a, 0x5f, 0xcc, 0x6a, 0xa8, 0x82, 0x5a, 0x6f, - 0x28, 0x4a, 0xf5, 0xb6, 0x79, 0x49, 0x7c, 0x77, 0x18, 0xaa, 0xc9, 0xb0, 0xe0, 0xe2, 0x37, 0x00, - 0x00, 0xff, 0xff, 0x2a, 0xed, 0x9f, 0x7b, 0x83, 0x01, 0x00, 0x00, -} - -func (m *GenesisState) 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 *GenesisState) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - { - size, err := m.Params.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenesis(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - -func encodeVarintGenesis(dAtA []byte, offset int, v uint64) int { - offset -= sovGenesis(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ - } - dAtA[offset] = uint8(v) - return base -} -func (m *GenesisState) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = m.Params.Size() - n += 1 + l + sovGenesis(uint64(l)) - return n -} - -func sovGenesis(x uint64) (n int) { - return (math_bits.Len64(x|1) + 6) / 7 -} -func sozGenesis(x uint64) (n int) { - return sovGenesis(uint64((x << 1) ^ uint64((int64(x) >> 63)))) -} -func (m *GenesisState) 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 ErrIntOverflowGenesis - } - 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: GenesisState: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: GenesisState: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenesis - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenesis - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenesis - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenesis(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenesis - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func skipGenesis(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, ErrIntOverflowGenesis - } - 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, ErrIntOverflowGenesis - } - 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, ErrIntOverflowGenesis - } - 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, ErrInvalidLengthGenesis - } - iNdEx += length - case 3: - depth++ - case 4: - if depth == 0 { - return 0, ErrUnexpectedEndOfGroupGenesis - } - depth-- - case 5: - iNdEx += 4 - default: - return 0, fmt.Errorf("proto: illegal wireType %d", wireType) - } - if iNdEx < 0 { - return 0, ErrInvalidLengthGenesis - } - if depth == 0 { - return iNdEx, nil - } - } - return 0, io.ErrUnexpectedEOF -} - -var ( - ErrInvalidLengthGenesis = fmt.Errorf("proto: negative length found during unmarshaling") - ErrIntOverflowGenesis = fmt.Errorf("proto: integer overflow") - ErrUnexpectedEndOfGroupGenesis = fmt.Errorf("proto: unexpected end of group") -) diff --git a/x/validator-preference/types/params.go b/x/validator-preference/types/params.go deleted file mode 100644 index 792d51fae36..00000000000 --- a/x/validator-preference/types/params.go +++ /dev/null @@ -1,62 +0,0 @@ -package types - -import ( - "fmt" - - appparams "github.com/osmosis-labs/osmosis/v12/app/params" - - sdk "github.com/cosmos/cosmos-sdk/types" - paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" -) - -// Parameter store keys. -var ( - KeyValSetCreationFee = []byte("ValSetCreationFee") -) - -// ParamTable for gamm module. -func ParamKeyTable() paramtypes.KeyTable { - return paramtypes.NewKeyTable().RegisterParamSet(&Params{}) -} - -func NewParams(valSetCreationFee sdk.Coins) Params { - return Params{ - ValsetCreationFee: valSetCreationFee, - } -} - -// default gamm module parameters. -func DefaultParams() Params { - return Params{ - ValsetCreationFee: sdk.NewCoins(sdk.NewInt64Coin(appparams.BaseCoinUnit, 10_000_000)), // 10 OSMO - } -} - -// validate params. -func (p Params) Validate() error { - if err := validateValSetCreationFee(p.ValsetCreationFee); err != nil { - return err - } - - return nil -} - -// Implements params.ParamSet. -func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs { - return paramtypes.ParamSetPairs{ - paramtypes.NewParamSetPair(KeyValSetCreationFee, &p.ValsetCreationFee, validateValSetCreationFee), - } -} - -func validateValSetCreationFee(i interface{}) error { - v, ok := i.(sdk.Coins) - if !ok { - return fmt.Errorf("invalid parameter type: %T", i) - } - - if v.Validate() != nil { - return fmt.Errorf("invalid val-set creation fee: %+v", i) - } - - return nil -} diff --git a/x/validator-preference/types/params.pb.go b/x/validator-preference/types/params.pb.go deleted file mode 100644 index 462ca83e3f3..00000000000 --- a/x/validator-preference/types/params.pb.go +++ /dev/null @@ -1,341 +0,0 @@ -// Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: osmosis/validator-preference/v1beta1/params.proto - -package types - -import ( - fmt "fmt" - _ "github.com/cosmos/cosmos-proto" - github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types" - types "github.com/cosmos/cosmos-sdk/types" - _ "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 - -// Params defines the parameters for the module. -type Params struct { - ValsetCreationFee github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,1,rep,name=valset_creation_fee,json=valsetCreationFee,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"valset_creation_fee" yaml:"valset_creation_fee"` -} - -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_db06f71db3b2b0f5, []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) GetValsetCreationFee() github_com_cosmos_cosmos_sdk_types.Coins { - if m != nil { - return m.ValsetCreationFee - } - return nil -} - -func init() { - proto.RegisterType((*Params)(nil), "osmosis.validatorpreference.v1beta1.Params") -} - -func init() { - proto.RegisterFile("osmosis/validator-preference/v1beta1/params.proto", fileDescriptor_db06f71db3b2b0f5) -} - -var fileDescriptor_db06f71db3b2b0f5 = []byte{ - // 296 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x91, 0xb1, 0x4e, 0xc3, 0x30, - 0x10, 0x86, 0x63, 0x21, 0x75, 0x28, 0x13, 0x85, 0x81, 0x66, 0x70, 0x50, 0x58, 0xba, 0xc4, 0x56, - 0xca, 0xc6, 0x84, 0x5a, 0x89, 0x11, 0x21, 0xc6, 0x2e, 0x91, 0x93, 0x5e, 0x83, 0x45, 0x12, 0x47, - 0xb6, 0x89, 0xe8, 0x5b, 0xb0, 0xb2, 0x33, 0xf1, 0x24, 0x1d, 0x3b, 0x32, 0x15, 0x94, 0xbc, 0x01, - 0x4f, 0x80, 0x6a, 0x9b, 0x96, 0xa1, 0x53, 0x72, 0x3a, 0x7f, 0xdf, 0xfd, 0xba, 0xeb, 0xc7, 0x42, - 0x95, 0x42, 0x71, 0x45, 0x1b, 0x56, 0xf0, 0x39, 0xd3, 0x42, 0x46, 0xb5, 0x84, 0x05, 0x48, 0xa8, - 0x32, 0xa0, 0x4d, 0x9c, 0x82, 0x66, 0x31, 0xad, 0x99, 0x64, 0xa5, 0x22, 0xb5, 0x14, 0x5a, 0x0c, - 0x2e, 0x1d, 0x42, 0x76, 0xc8, 0x9e, 0x20, 0x8e, 0xf0, 0xcf, 0x72, 0x91, 0x0b, 0xf3, 0x9e, 0x6e, - 0xff, 0x2c, 0xea, 0x0f, 0x33, 0xc3, 0x26, 0xb6, 0x61, 0x0b, 0xd7, 0xc2, 0xb6, 0xa2, 0x29, 0x53, - 0xfb, 0xb9, 0x99, 0xe0, 0x95, 0xed, 0x87, 0xef, 0xa8, 0xdf, 0xbb, 0x37, 0x31, 0x06, 0x6f, 0xa8, - 0x7f, 0xda, 0xb0, 0x42, 0x81, 0x4e, 0x32, 0x09, 0x4c, 0x73, 0x51, 0x25, 0x0b, 0x80, 0x73, 0x74, - 0x71, 0x34, 0x3a, 0x1e, 0x0f, 0x89, 0xf3, 0x6e, 0x4d, 0x7f, 0x79, 0xc8, 0x54, 0xf0, 0x6a, 0x72, - 0xb7, 0xda, 0x04, 0xde, 0xcf, 0x26, 0xf0, 0x97, 0xac, 0x2c, 0xae, 0xc3, 0x03, 0x8e, 0xf0, 0xe3, - 0x2b, 0x18, 0xe5, 0x5c, 0x3f, 0x3e, 0xa7, 0x24, 0x13, 0xa5, 0x8b, 0xe8, 0x3e, 0x91, 0x9a, 0x3f, - 0x51, 0xbd, 0xac, 0x41, 0x19, 0x9d, 0x7a, 0x38, 0xb1, 0x86, 0xa9, 0x13, 0xdc, 0x02, 0x4c, 0x66, - 0xab, 0x16, 0xa3, 0x75, 0x8b, 0xd1, 0x77, 0x8b, 0xd1, 0x6b, 0x87, 0xbd, 0x75, 0x87, 0xbd, 0xcf, - 0x0e, 0x7b, 0xb3, 0x9b, 0x7f, 0x5a, 0xb7, 0xc1, 0xa8, 0x60, 0xa9, 0xa2, 0xbb, 0x0b, 0xc4, 0x63, - 0xfa, 0x72, 0xf8, 0x0e, 0x66, 0x68, 0xda, 0x33, 0x9b, 0xb8, 0xfa, 0x0d, 0x00, 0x00, 0xff, 0xff, - 0x55, 0x97, 0x65, 0x82, 0xb4, 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.ValsetCreationFee) > 0 { - for iNdEx := len(m.ValsetCreationFee) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.ValsetCreationFee[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintParams(dAtA, i, uint64(size)) - } - 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.ValsetCreationFee) > 0 { - for _, e := range m.ValsetCreationFee { - l = e.Size() - 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 ValsetCreationFee", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowParams - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthParams - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthParams - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ValsetCreationFee = append(m.ValsetCreationFee, types.Coin{}) - if err := m.ValsetCreationFee[len(m.ValsetCreationFee)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - 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") -) diff --git a/x/validator-preference/README.md b/x/valset-pref/README.md similarity index 100% rename from x/validator-preference/README.md rename to x/valset-pref/README.md diff --git a/x/valset-pref/client/query_proto_wrap.go b/x/valset-pref/client/query_proto_wrap.go new file mode 100644 index 00000000000..401585539d9 --- /dev/null +++ b/x/valset-pref/client/query_proto_wrap.go @@ -0,0 +1,22 @@ +package client + +import ( + "context" + + validatorprefkeeper "github.com/osmosis-labs/osmosis/v12/x/valset-pref" + "github.com/osmosis-labs/osmosis/v12/x/valset-pref/client/queryproto" +) + +type Querier struct { + K validatorprefkeeper.Keeper +} + +var _ queryproto.QueryServer = Querier{} + +func NewQuerier(k validatorprefkeeper.Keeper) Querier { + return Querier{K: k} +} + +func (q Querier) UserValidatorPreferences(ctx context.Context, req *queryproto.QueryUserValidatorPreferences) (*queryproto.QueryUserValidatorPreferenceResponse, error) { + return &queryproto.QueryUserValidatorPreferenceResponse{}, nil +} diff --git a/x/validator-preference/client/queryproto/query.pb.go b/x/valset-pref/client/queryproto/query.pb.go similarity index 81% rename from x/validator-preference/client/queryproto/query.pb.go rename to x/valset-pref/client/queryproto/query.pb.go index 3af9d73e681..4c160f8c932 100644 --- a/x/validator-preference/client/queryproto/query.pb.go +++ b/x/valset-pref/client/queryproto/query.pb.go @@ -1,5 +1,5 @@ // Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: osmosis/validator-preference/v1beta1/query.proto +// source: osmosis/valset-pref/v1beta1/query.proto package queryproto @@ -9,7 +9,7 @@ import ( _ "github.com/gogo/protobuf/gogoproto" grpc1 "github.com/gogo/protobuf/grpc" proto "github.com/gogo/protobuf/proto" - types "github.com/osmosis-labs/osmosis/v12/x/validator-preference/types" + types "github.com/osmosis-labs/osmosis/v12/x/valset-pref/types" _ "google.golang.org/genproto/googleapis/api/annotations" grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" @@ -33,14 +33,14 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // Request type for UserValidatorPreferences. type QueryUserValidatorPreferences struct { // user account address - User string `protobuf:"bytes,1,opt,name=user,proto3" json:"user,omitempty"` + Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` } func (m *QueryUserValidatorPreferences) Reset() { *m = QueryUserValidatorPreferences{} } func (m *QueryUserValidatorPreferences) String() string { return proto.CompactTextString(m) } func (*QueryUserValidatorPreferences) ProtoMessage() {} func (*QueryUserValidatorPreferences) Descriptor() ([]byte, []int) { - return fileDescriptor_888a45acbabdd269, []int{0} + return fileDescriptor_9ffbeb4123fe56ae, []int{0} } func (m *QueryUserValidatorPreferences) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -78,7 +78,7 @@ func (m *QueryUserValidatorPreferenceResponse) Reset() { *m = QueryUserV func (m *QueryUserValidatorPreferenceResponse) String() string { return proto.CompactTextString(m) } func (*QueryUserValidatorPreferenceResponse) ProtoMessage() {} func (*QueryUserValidatorPreferenceResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_888a45acbabdd269, []int{1} + return fileDescriptor_9ffbeb4123fe56ae, []int{1} } func (m *QueryUserValidatorPreferenceResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -108,37 +108,37 @@ func (m *QueryUserValidatorPreferenceResponse) XXX_DiscardUnknown() { var xxx_messageInfo_QueryUserValidatorPreferenceResponse proto.InternalMessageInfo func init() { - proto.RegisterType((*QueryUserValidatorPreferences)(nil), "osmosis.validatorpreference.v1beta1.QueryUserValidatorPreferences") - proto.RegisterType((*QueryUserValidatorPreferenceResponse)(nil), "osmosis.validatorpreference.v1beta1.QueryUserValidatorPreferenceResponse") + proto.RegisterType((*QueryUserValidatorPreferences)(nil), "osmosis.valsetpref.v1beta1.QueryUserValidatorPreferences") + proto.RegisterType((*QueryUserValidatorPreferenceResponse)(nil), "osmosis.valsetpref.v1beta1.QueryUserValidatorPreferenceResponse") } func init() { - proto.RegisterFile("osmosis/validator-preference/v1beta1/query.proto", fileDescriptor_888a45acbabdd269) + proto.RegisterFile("osmosis/valset-pref/v1beta1/query.proto", fileDescriptor_9ffbeb4123fe56ae) } -var fileDescriptor_888a45acbabdd269 = []byte{ +var fileDescriptor_9ffbeb4123fe56ae = []byte{ // 338 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x32, 0xc8, 0x2f, 0xce, 0xcd, - 0x2f, 0xce, 0x2c, 0xd6, 0x2f, 0x4b, 0xcc, 0xc9, 0x4c, 0x49, 0x2c, 0xc9, 0x2f, 0xd2, 0x2d, 0x28, - 0x4a, 0x4d, 0x4b, 0x2d, 0x4a, 0xcd, 0x4b, 0x4e, 0xd5, 0x2f, 0x33, 0x4c, 0x4a, 0x2d, 0x49, 0x34, - 0xd4, 0x2f, 0x2c, 0x4d, 0x2d, 0xaa, 0xd4, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x52, 0x86, 0xea, - 0xd0, 0x83, 0xeb, 0x40, 0x68, 0xd0, 0x83, 0x6a, 0x90, 0x12, 0x49, 0xcf, 0x4f, 0xcf, 0x07, 0xab, - 0xd7, 0x07, 0xb1, 0x20, 0x5a, 0xa5, 0x64, 0xd2, 0xf3, 0xf3, 0xd3, 0x73, 0x52, 0xf5, 0x13, 0x0b, - 0x32, 0xf5, 0x13, 0xf3, 0xf2, 0xf2, 0x4b, 0x12, 0x4b, 0x32, 0xf3, 0xf3, 0x8a, 0xa1, 0xb2, 0xc4, - 0x39, 0xa5, 0xb8, 0x24, 0xb1, 0x24, 0x15, 0xa2, 0x43, 0xc9, 0x98, 0x4b, 0x36, 0x10, 0xe4, 0xb2, - 0xd0, 0xe2, 0xd4, 0xa2, 0x30, 0x98, 0xa6, 0x00, 0xb8, 0x9e, 0x62, 0x21, 0x21, 0x2e, 0x96, 0xd2, - 0xe2, 0xd4, 0x22, 0x09, 0x46, 0x05, 0x46, 0x0d, 0xce, 0x20, 0x30, 0x5b, 0xa9, 0x83, 0x91, 0x4b, - 0x05, 0x9f, 0xae, 0xa0, 0xd4, 0xe2, 0x82, 0xfc, 0xbc, 0xe2, 0x54, 0xa1, 0x04, 0x2e, 0x6e, 0x84, - 0xfd, 0xc5, 0x12, 0x8c, 0x0a, 0xcc, 0x1a, 0xdc, 0x46, 0x16, 0x7a, 0x44, 0x78, 0x5f, 0x0f, 0x8b, - 0xb1, 0x4e, 0x2c, 0x27, 0xee, 0xc9, 0x33, 0x04, 0x21, 0x1b, 0x69, 0xf4, 0x92, 0x91, 0x8b, 0x15, - 0xec, 0x14, 0xa1, 0xfb, 0x8c, 0x5c, 0x12, 0x38, 0x7d, 0xe1, 0x44, 0x94, 0x9d, 0x78, 0x43, 0x42, - 0xca, 0x93, 0x62, 0x33, 0x60, 0xe1, 0xa2, 0x64, 0xd2, 0x74, 0xf9, 0xc9, 0x64, 0x26, 0x3d, 0x21, - 0x1d, 0x7d, 0xa2, 0x22, 0xac, 0x1a, 0x14, 0xea, 0xb5, 0x4e, 0x59, 0x27, 0x1e, 0xca, 0x31, 0x9c, - 0x78, 0x24, 0xc7, 0x78, 0xe1, 0x91, 0x1c, 0xe3, 0x83, 0x47, 0x72, 0x8c, 0x13, 0x1e, 0xcb, 0x31, - 0x5c, 0x78, 0x2c, 0xc7, 0x70, 0xe3, 0xb1, 0x1c, 0x43, 0x94, 0x4f, 0x7a, 0x66, 0x49, 0x46, 0x69, - 0x92, 0x5e, 0x72, 0x7e, 0x2e, 0xcc, 0x54, 0xdd, 0x9c, 0xc4, 0xa4, 0x62, 0x84, 0x15, 0x86, 0x46, - 0xfa, 0x15, 0xd8, 0x2d, 0x4a, 0xce, 0xc9, 0x4c, 0xcd, 0x2b, 0x81, 0xa4, 0x51, 0x70, 0xba, 0x48, - 0x62, 0x03, 0x53, 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0x44, 0xbd, 0xf5, 0xa9, 0xdd, 0x02, + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x92, 0xcd, 0x4a, 0x03, 0x31, + 0x14, 0x85, 0x27, 0xfe, 0x62, 0xba, 0x1b, 0x5c, 0x0c, 0x83, 0xc6, 0x52, 0x44, 0xbb, 0x69, 0x42, + 0xeb, 0xaa, 0x3b, 0xa9, 0x2f, 0xa0, 0x05, 0x15, 0xdc, 0x65, 0xda, 0xdb, 0x71, 0x60, 0x3a, 0x19, + 0x73, 0xd3, 0xa2, 0x88, 0x08, 0x3e, 0x81, 0xe0, 0x43, 0xd9, 0x65, 0xc5, 0x8d, 0x2b, 0xd1, 0xd6, + 0x07, 0x91, 0xce, 0x0f, 0x55, 0xb0, 0xb3, 0x70, 0x95, 0x84, 0x7c, 0xf7, 0x9c, 0x7b, 0x72, 0x43, + 0xf7, 0x15, 0xf6, 0x15, 0x06, 0x28, 0x86, 0x32, 0x44, 0x30, 0xb5, 0x58, 0x43, 0x4f, 0x0c, 0xeb, + 0x1e, 0x18, 0x59, 0x17, 0x57, 0x03, 0xd0, 0x37, 0x3c, 0xd6, 0xca, 0x28, 0xdb, 0xcd, 0x40, 0x9e, + 0x82, 0x33, 0x8e, 0x67, 0x9c, 0xbb, 0xe9, 0x2b, 0x5f, 0x25, 0x98, 0x98, 0xed, 0xd2, 0x0a, 0x77, + 0xcb, 0x57, 0xca, 0x0f, 0x41, 0xc8, 0x38, 0x10, 0x32, 0x8a, 0x94, 0x91, 0x26, 0x50, 0x11, 0x66, + 0xb7, 0x85, 0xc6, 0x68, 0xa4, 0x81, 0x14, 0xac, 0x34, 0xe9, 0xf6, 0xc9, 0xac, 0x8f, 0x53, 0x04, + 0x7d, 0x26, 0xc3, 0xa0, 0x2b, 0x8d, 0xd2, 0xc7, 0x1a, 0x7a, 0xa0, 0x21, 0xea, 0x00, 0xda, 0x0e, + 0x5d, 0x97, 0xdd, 0xae, 0x06, 0x44, 0x87, 0x94, 0x49, 0x75, 0xa3, 0x9d, 0x1f, 0x2b, 0xf7, 0x74, + 0xb7, 0xa8, 0xb4, 0x0d, 0x18, 0xab, 0x08, 0xc1, 0x3e, 0xa7, 0xa5, 0x78, 0x2e, 0xe8, 0x90, 0xf2, + 0x72, 0xb5, 0xd4, 0x10, 0x7c, 0x71, 0x62, 0xfe, 0x87, 0x5a, 0x6b, 0x65, 0xf4, 0xbe, 0x63, 0xb5, + 0x7f, 0x2a, 0x35, 0x5e, 0x08, 0x5d, 0x4d, 0x3a, 0xb0, 0x9f, 0x09, 0x75, 0x16, 0x26, 0x68, 0x16, + 0x59, 0x15, 0x86, 0x77, 0x0f, 0xff, 0x5b, 0x9a, 0x87, 0xaf, 0xf0, 0x87, 0xd7, 0xaf, 0xa7, 0xa5, + 0xaa, 0xbd, 0x27, 0x8a, 0x26, 0x72, 0x9b, 0xbd, 0xe9, 0x5d, 0x4b, 0x8e, 0x3e, 0x99, 0x35, 0x9a, + 0x30, 0x32, 0x9e, 0x30, 0xf2, 0x31, 0x61, 0xe4, 0x71, 0xca, 0xac, 0xf1, 0x94, 0x59, 0x6f, 0x53, + 0x66, 0x5d, 0x1c, 0xf9, 0x81, 0xb9, 0x1c, 0x78, 0xbc, 0xa3, 0xfa, 0xb9, 0x5e, 0x2d, 0x94, 0x1e, + 0xce, 0xc5, 0xeb, 0x0d, 0x71, 0xfd, 0xcb, 0xa2, 0x13, 0x06, 0x10, 0x99, 0xf4, 0xb3, 0x25, 0x23, + 0xf7, 0xd6, 0x92, 0xe5, 0xe0, 0x3b, 0x00, 0x00, 0xff, 0xff, 0xbd, 0xc4, 0xe6, 0x56, 0x9d, 0x02, 0x00, 0x00, } @@ -168,7 +168,7 @@ func NewQueryClient(cc grpc1.ClientConn) QueryClient { func (c *queryClient) UserValidatorPreferences(ctx context.Context, in *QueryUserValidatorPreferences, opts ...grpc.CallOption) (*QueryUserValidatorPreferenceResponse, error) { out := new(QueryUserValidatorPreferenceResponse) - err := c.cc.Invoke(ctx, "/osmosis.validatorpreference.v1beta1.Query/UserValidatorPreferences", in, out, opts...) + err := c.cc.Invoke(ctx, "/osmosis.valsetpref.v1beta1.Query/UserValidatorPreferences", in, out, opts...) if err != nil { return nil, err } @@ -203,7 +203,7 @@ func _Query_UserValidatorPreferences_Handler(srv interface{}, ctx context.Contex } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/osmosis.validatorpreference.v1beta1.Query/UserValidatorPreferences", + FullMethod: "/osmosis.valsetpref.v1beta1.Query/UserValidatorPreferences", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(QueryServer).UserValidatorPreferences(ctx, req.(*QueryUserValidatorPreferences)) @@ -212,7 +212,7 @@ func _Query_UserValidatorPreferences_Handler(srv interface{}, ctx context.Contex } var _Query_serviceDesc = grpc.ServiceDesc{ - ServiceName: "osmosis.validatorpreference.v1beta1.Query", + ServiceName: "osmosis.valsetpref.v1beta1.Query", HandlerType: (*QueryServer)(nil), Methods: []grpc.MethodDesc{ { @@ -221,7 +221,7 @@ var _Query_serviceDesc = grpc.ServiceDesc{ }, }, Streams: []grpc.StreamDesc{}, - Metadata: "osmosis/validator-preference/v1beta1/query.proto", + Metadata: "osmosis/valset-pref/v1beta1/query.proto", } func (m *QueryUserValidatorPreferences) Marshal() (dAtA []byte, err error) { @@ -244,10 +244,10 @@ func (m *QueryUserValidatorPreferences) MarshalToSizedBuffer(dAtA []byte) (int, _ = i var l int _ = l - if len(m.User) > 0 { - i -= len(m.User) - copy(dAtA[i:], m.User) - i = encodeVarintQuery(dAtA, i, uint64(len(m.User))) + if len(m.Address) > 0 { + i -= len(m.Address) + copy(dAtA[i:], m.Address) + i = encodeVarintQuery(dAtA, i, uint64(len(m.Address))) i-- dAtA[i] = 0xa } @@ -308,7 +308,7 @@ func (m *QueryUserValidatorPreferences) Size() (n int) { } var l int _ = l - l = len(m.User) + l = len(m.Address) if l > 0 { n += 1 + l + sovQuery(uint64(l)) } @@ -367,7 +367,7 @@ func (m *QueryUserValidatorPreferences) Unmarshal(dAtA []byte) error { switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field User", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -395,7 +395,7 @@ func (m *QueryUserValidatorPreferences) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.User = string(dAtA[iNdEx:postIndex]) + m.Address = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex diff --git a/x/validator-preference/client/queryproto/query.pb.gw.go b/x/valset-pref/client/queryproto/query.pb.gw.go similarity index 92% rename from x/validator-preference/client/queryproto/query.pb.gw.go rename to x/valset-pref/client/queryproto/query.pb.gw.go index 00172683446..c79a1f8f501 100644 --- a/x/validator-preference/client/queryproto/query.pb.gw.go +++ b/x/valset-pref/client/queryproto/query.pb.gw.go @@ -1,5 +1,5 @@ // Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. -// source: osmosis/validator-preference/v1beta1/query.proto +// source: osmosis/valset-pref/v1beta1/query.proto /* Package queryproto is a reverse proxy. @@ -44,15 +44,15 @@ func request_Query_UserValidatorPreferences_0(ctx context.Context, marshaler run _ = err ) - val, ok = pathParams["user"] + val, ok = pathParams["address"] if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "user") + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "address") } - protoReq.User, err = runtime.String(val) + protoReq.Address, err = runtime.String(val) if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "user", err) + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "address", err) } msg, err := client.UserValidatorPreferences(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) @@ -71,15 +71,15 @@ func local_request_Query_UserValidatorPreferences_0(ctx context.Context, marshal _ = err ) - val, ok = pathParams["user"] + val, ok = pathParams["address"] if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "user") + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "address") } - protoReq.User, err = runtime.String(val) + protoReq.Address, err = runtime.String(val) if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "user", err) + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "address", err) } msg, err := server.UserValidatorPreferences(ctx, &protoReq) @@ -181,7 +181,7 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie } var ( - pattern_Query_UserValidatorPreferences_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"osmosis", "validator-preference", "v1beta1", "user"}, "", runtime.AssumeColonVerbOpt(false))) + pattern_Query_UserValidatorPreferences_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"osmosis", "valset-pref", "v1beta1", "address"}, "", runtime.AssumeColonVerbOpt(false))) ) var ( diff --git a/x/validator-preference/keeper.go b/x/valset-pref/keeper.go similarity index 58% rename from x/validator-preference/keeper.go rename to x/valset-pref/keeper.go index 2ea82aa35b7..ffa5184e1e8 100644 --- a/x/validator-preference/keeper.go +++ b/x/valset-pref/keeper.go @@ -9,33 +9,23 @@ import ( paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" "github.com/gogo/protobuf/proto" "github.com/osmosis-labs/osmosis/v12/osmoutils" - "github.com/osmosis-labs/osmosis/v12/x/validator-preference/types" + "github.com/osmosis-labs/osmosis/v12/x/valset-pref/types" ) type Keeper struct { storeKey sdk.StoreKey paramSpace paramtypes.Subspace stakingKeeper types.StakingInterface - bankKeeper types.BankInterface - distrKeeper types.DistrInterface } func NewKeeper(storeKey sdk.StoreKey, paramSpace paramtypes.Subspace, stakingKeeper types.StakingInterface, - bankKeeper types.BankInterface, - distrKeeper types.DistrInterface, ) Keeper { - if !paramSpace.HasKeyTable() { - paramSpace = paramSpace.WithKeyTable(types.ParamKeyTable()) - } - return Keeper{ storeKey: storeKey, paramSpace: paramSpace, stakingKeeper: stakingKeeper, - bankKeeper: bankKeeper, - distrKeeper: distrKeeper, } } @@ -49,29 +39,15 @@ func (k Keeper) SetValidatorSetPreferences(ctx sdk.Context, delegator string, va } func (k Keeper) GetValidatorSetPreference(ctx sdk.Context, delegator string) (types.ValidatorSetPreferences, bool) { - validatorSet := types.ValidatorSetPreferences{} - store := ctx.KVStore(k.storeKey) - b := store.Get([]byte(delegator)) - if b == nil { + bz := store.Get([]byte(delegator)) + if bz == nil { return types.ValidatorSetPreferences{}, false } - - err := proto.Unmarshal(b, &validatorSet) - if err != nil { + var valsetPref types.ValidatorSetPreferences + if err := proto.Unmarshal(bz, &valsetPref); err != nil { return types.ValidatorSetPreferences{}, false } - return validatorSet, true -} - -// GetParams returns the total set params. -func (k Keeper) GetParams(ctx sdk.Context) (params types.Params) { - k.paramSpace.GetParamSet(ctx, ¶ms) - return params -} - -// SetParams sets the total set of params. -func (k Keeper) SetParams(ctx sdk.Context, params types.Params) { - k.paramSpace.SetParamSet(ctx, ¶ms) + return valsetPref, true } diff --git a/x/validator-preference/keeper_test.go b/x/valset-pref/keeper_test.go similarity index 94% rename from x/validator-preference/keeper_test.go rename to x/valset-pref/keeper_test.go index 795a6aaca62..3498c2eccda 100644 --- a/x/validator-preference/keeper_test.go +++ b/x/valset-pref/keeper_test.go @@ -6,7 +6,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/osmosis-labs/osmosis/v12/app/apptesting" - "github.com/osmosis-labs/osmosis/v12/x/validator-preference/types" + "github.com/osmosis-labs/osmosis/v12/x/valset-pref/types" "github.com/stretchr/testify/suite" ) diff --git a/x/validator-preference/msg_server.go b/x/valset-pref/msg_server.go similarity index 62% rename from x/validator-preference/msg_server.go rename to x/valset-pref/msg_server.go index aa921501e4c..22be1b7ff88 100644 --- a/x/validator-preference/msg_server.go +++ b/x/valset-pref/msg_server.go @@ -2,10 +2,9 @@ package keeper import ( "context" - "fmt" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/osmosis-labs/osmosis/v12/x/validator-preference/types" + "github.com/osmosis-labs/osmosis/v12/x/valset-pref/types" ) type msgServer struct { @@ -25,32 +24,11 @@ var _ types.MsgServer = msgServer{} func (server msgServer) SetValidatorSetPreference(goCtx context.Context, msg *types.MsgSetValidatorSetPreference) (*types.MsgSetValidatorSetPreferenceResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) - // new user preference - preferences := msg.Preferences - - // check if a user already has a validator-set created - existingValidators, found := server.keeper.GetValidatorSetPreference(ctx, msg.Delegator) - if found { - // check if the new preferences is the same as the existing preferences - isEqual := server.keeper.SortAndCompareValidatorSet(preferences, existingValidators.Preferences) - if isEqual { - return nil, fmt.Errorf("The preferences (validator and weights) are the same") - } - } - - // checks that all the validators exist on chain - err := server.keeper.ValidatePreferences(ctx, preferences) - if err != nil { - return nil, err - } - - // charge fee to execute this message - err = server.keeper.ChargeForCreateValSet(ctx, msg.Delegator) + err := server.keeper.SetupValidatorSetPreference(ctx, msg.Delegator, msg.Preferences) if err != nil { return nil, err } - // create/update the validator-set based on what user provides setMsg := types.ValidatorSetPreferences{ Preferences: msg.Preferences, } diff --git a/x/validator-preference/msg_server_test.go b/x/valset-pref/msg_server_test.go similarity index 55% rename from x/validator-preference/msg_server_test.go rename to x/valset-pref/msg_server_test.go index 966764e3ee4..2a97e899068 100644 --- a/x/validator-preference/msg_server_test.go +++ b/x/valset-pref/msg_server_test.go @@ -2,8 +2,8 @@ package keeper_test import ( sdk "github.com/cosmos/cosmos-sdk/types" - valPref "github.com/osmosis-labs/osmosis/v12/x/validator-preference" - "github.com/osmosis-labs/osmosis/v12/x/validator-preference/types" + valPref "github.com/osmosis-labs/osmosis/v12/x/valset-pref" + "github.com/osmosis-labs/osmosis/v12/x/valset-pref/types" ) func (suite *KeeperTestSuite) TestSetValidatorSetPreference() { @@ -16,7 +16,6 @@ func (suite *KeeperTestSuite) TestSetValidatorSetPreference() { name string delegator sdk.AccAddress preferences []types.ValidatorPreference - creationFee sdk.Coins expectPass bool }{ { @@ -36,85 +35,88 @@ func (suite *KeeperTestSuite) TestSetValidatorSetPreference() { Weight: sdk.NewDecWithPrec(2, 1), }, }, - creationFee: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(10))), - expectPass: true, + expectPass: true, }, { - name: "update existing validator with same values as previous one", + name: "update 2 validator weights but leave the 3rd one as is", delegator: sdk.AccAddress([]byte("addr1---------------")), preferences: []types.ValidatorPreference{ - { - ValOperAddress: valAddrs[1], - Weight: sdk.NewDecWithPrec(3, 1), - }, { ValOperAddress: valAddrs[0], Weight: sdk.NewDecWithPrec(5, 1), }, + { + ValOperAddress: valAddrs[1], + Weight: sdk.NewDecWithPrec(4, 1), + }, { ValOperAddress: valAddrs[2], - Weight: sdk.NewDecWithPrec(2, 1), + Weight: sdk.NewDecWithPrec(1, 1), }, }, - creationFee: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(10))), - expectPass: false, + expectPass: true, }, { - name: "create validator set with unknown validator address", - delegator: sdk.AccAddress([]byte("addr2---------------")), + name: "update existing validator with same valAddr and weights", + delegator: sdk.AccAddress([]byte("addr1---------------")), preferences: []types.ValidatorPreference{ { - ValOperAddress: "addr1---------------", - Weight: sdk.NewDec(1), + ValOperAddress: valAddrs[0], + Weight: sdk.NewDecWithPrec(5, 1), + }, + { + ValOperAddress: valAddrs[1], + Weight: sdk.NewDecWithPrec(4, 1), + }, + { + ValOperAddress: valAddrs[2], + Weight: sdk.NewDecWithPrec(1, 1), }, }, - creationFee: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(10))), - expectPass: false, + expectPass: false, }, { - name: "creation of new validator set with 0 fees", - delegator: sdk.AccAddress([]byte("addr3---------------")), + name: "update existing validator with same valAddr but different weights", + delegator: sdk.AccAddress([]byte("addr1---------------")), preferences: []types.ValidatorPreference{ { ValOperAddress: valAddrs[0], - Weight: sdk.NewDecWithPrec(5, 1), + Weight: sdk.NewDecWithPrec(1, 1), }, { ValOperAddress: valAddrs[1], - Weight: sdk.NewDecWithPrec(5, 1), + Weight: sdk.NewDecWithPrec(2, 1), + }, + { + ValOperAddress: valAddrs[2], + Weight: sdk.NewDecWithPrec(7, 1), }, }, - creationFee: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(0))), - expectPass: false, + expectPass: true, + }, + { + name: "create validator set with unknown validator address", + delegator: sdk.AccAddress([]byte("addr1---------------")), + preferences: []types.ValidatorPreference{ + { + ValOperAddress: "addr1---------------", + Weight: sdk.NewDec(1), + }, + }, + expectPass: false, }, } for _, test := range tests { suite.Run(test.name, func() { - - bankKeeper := suite.App.BankKeeper - - // fund the account that is trying to delegate - suite.FundAcc(test.delegator, sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, 100)}) - initialBalance := bankKeeper.GetBalance(suite.Ctx, test.delegator, sdk.DefaultBondDenom).Amount - - // set the creation fee - suite.App.ValidatorPreferenceKeeper.SetParams(suite.Ctx, types.Params{ - ValsetCreationFee: test.creationFee, - }) - // setup message server - msgServer := valPref.NewMsgServerImpl(suite.App.ValidatorPreferenceKeeper) + msgServer := valPref.NewMsgServerImpl(suite.App.ValidatorSetPreferenceKeeper) c := sdk.WrapSDKContext(suite.Ctx) // call the create validator set preference _, err := msgServer.SetValidatorSetPreference(c, types.NewMsgSetValidatorSetPreference(test.delegator, test.preferences)) if test.expectPass { suite.Require().NoError(err) - - // check if the fee has been used - balance := bankKeeper.GetBalance(suite.Ctx, test.delegator, sdk.DefaultBondDenom).Amount - suite.Require().True(balance.LT(initialBalance)) } else { suite.Require().Error(err) } diff --git a/x/validator-preference/types/codec.go b/x/valset-pref/types/codec.go similarity index 55% rename from x/validator-preference/types/codec.go rename to x/valset-pref/types/codec.go index 7ae94351939..1c4b783cff4 100644 --- a/x/validator-preference/types/codec.go +++ b/x/valset-pref/types/codec.go @@ -8,9 +8,10 @@ import ( ) func RegisterCodec(cdc *codec.LegacyAmino) { - cdc.RegisterConcrete(&MsgSetValidatorSetPreference{}, "", nil) - cdc.RegisterConcrete(&MsgDelegateToValidatorSet{}, "", nil) - cdc.RegisterConcrete(&MsgUndelegateFromValidatorSet{}, "", nil) + cdc.RegisterConcrete(&MsgSetValidatorSetPreference{}, "osmosis/validator-set-preference/set-validator-set-preference", nil) + cdc.RegisterConcrete(&MsgDelegateToValidatorSet{}, "osmosis/validator-set-preference/delegate-to-validator-set", nil) + cdc.RegisterConcrete(&MsgUndelegateFromValidatorSet{}, "osmosis/validator-set-preference/undelegate-from-validator-set", nil) + cdc.RegisterConcrete(&MsgWithdrawDelegationRewards{}, "osmosis/validator-set-preference/withdraw-delegation-rewards", nil) } func RegisterInterfaces(registry cdctypes.InterfaceRegistry) { @@ -18,6 +19,7 @@ func RegisterInterfaces(registry cdctypes.InterfaceRegistry) { &MsgSetValidatorSetPreference{}, &MsgDelegateToValidatorSet{}, &MsgUndelegateFromValidatorSet{}, + &MsgWithdrawDelegationRewards{}, ) msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc) diff --git a/x/validator-preference/types/expected_interfaces.go b/x/valset-pref/types/expected_interfaces.go similarity index 67% rename from x/validator-preference/types/expected_interfaces.go rename to x/valset-pref/types/expected_interfaces.go index 193cfd11b91..7a54060e1d2 100644 --- a/x/validator-preference/types/expected_interfaces.go +++ b/x/valset-pref/types/expected_interfaces.go @@ -15,13 +15,3 @@ type StakingInterface interface { GetDelegation(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) (delegation stakingtypes.Delegation, found bool) Undelegate(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress, sharesAmount sdk.Dec) (time.Time, error) } - -// BankInterface defines the expected interface needed to retrieve account balances. -type BankInterface interface { - GetAllBalances(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins -} - -// DistrInterface defines the contract needed to be fulfilled for community pool interactions. -type DistrInterface interface { - FundCommunityPool(ctx sdk.Context, amount sdk.Coins, sender sdk.AccAddress) error -} diff --git a/x/validator-preference/types/keys.go b/x/valset-pref/types/keys.go similarity index 90% rename from x/validator-preference/types/keys.go rename to x/valset-pref/types/keys.go index 494bd472783..f5c7cc78cbc 100644 --- a/x/validator-preference/types/keys.go +++ b/x/valset-pref/types/keys.go @@ -2,7 +2,7 @@ package types var ( // ModuleName defines the module name - ModuleName = "validator-set-preference" + ModuleName = "validatorsetpreference" // StoreKey defines the primary module store key StoreKey = ModuleName diff --git a/x/validator-preference/types/msgs.go b/x/valset-pref/types/msgs.go similarity index 81% rename from x/validator-preference/types/msgs.go rename to x/valset-pref/types/msgs.go index 15e53f45e02..77b24a71eb6 100644 --- a/x/validator-preference/types/msgs.go +++ b/x/valset-pref/types/msgs.go @@ -144,3 +144,37 @@ func (m MsgUndelegateFromValidatorSet) GetSigners() []sdk.AccAddress { delegator, _ := sdk.AccAddressFromBech32(m.Delegator) return []sdk.AccAddress{delegator} } + +// constants +const ( + TypeMsgWithdrawDelegationRewards = "withdraw_delegation_rewards" +) + +var _ sdk.Msg = &MsgWithdrawDelegationRewards{} + +// NewMsgMsgStakeToValidatorSet creates a msg to stake to a validator. +func NewMsgWithdrawDelegationRewards(delegator sdk.AccAddress) *MsgWithdrawDelegationRewards { + return &MsgWithdrawDelegationRewards{ + Delegator: delegator.String(), + } +} + +func (m MsgWithdrawDelegationRewards) Route() string { return RouterKey } +func (m MsgWithdrawDelegationRewards) Type() string { return TypeMsgWithdrawDelegationRewards } +func (m MsgWithdrawDelegationRewards) ValidateBasic() error { + _, err := sdk.AccAddressFromBech32(m.Delegator) + if err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "Invalid sender address (%s)", err) + } + + return nil +} + +func (m MsgWithdrawDelegationRewards) GetSignBytes() []byte { + return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&m)) +} + +func (m MsgWithdrawDelegationRewards) GetSigners() []sdk.AccAddress { + delegator, _ := sdk.AccAddressFromBech32(m.Delegator) + return []sdk.AccAddress{delegator} +} diff --git a/x/validator-preference/types/msgs_test.go b/x/valset-pref/types/msgs_test.go similarity index 81% rename from x/validator-preference/types/msgs_test.go rename to x/valset-pref/types/msgs_test.go index 3a02ed9ee16..47e05da50cb 100644 --- a/x/validator-preference/types/msgs_test.go +++ b/x/valset-pref/types/msgs_test.go @@ -8,7 +8,7 @@ import ( "github.com/osmosis-labs/osmosis/v12/app/apptesting" appParams "github.com/osmosis-labs/osmosis/v12/app/params" - "github.com/osmosis-labs/osmosis/v12/x/validator-preference/types" + "github.com/osmosis-labs/osmosis/v12/x/valset-pref/types" ) func TestMsgSetValidatorSetPreference(t *testing.T) { @@ -54,6 +54,10 @@ func TestMsgSetValidatorSetPreference(t *testing.T) { ValOperAddress: "osmovaloper1x2cfenmflhj3dwm2ph6nkgqr3nppkg86fxaymg", Weight: sdk.NewDecWithPrec(4, 1), }, + { + ValOperAddress: "osmovaloper1jcr68jghzm24zwe78zuhz7xahua8429erxk7vm", + Weight: sdk.NewDecWithPrec(2, 1), + }, }, }, expectPass: false, @@ -93,7 +97,7 @@ func TestMsgSetValidatorSetPreference(t *testing.T) { expectPass: false, }, { - name: "weights != 1", + name: "weights > 1", msg: types.MsgSetValidatorSetPreference{ Delegator: addr1, Preferences: []types.ValidatorPreference{ @@ -113,6 +117,27 @@ func TestMsgSetValidatorSetPreference(t *testing.T) { }, expectPass: false, }, + { + name: "weights < 1", + msg: types.MsgSetValidatorSetPreference{ + Delegator: addr1, + Preferences: []types.ValidatorPreference{ + { + ValOperAddress: "osmovaloper1x2cfenmflhj3dwm2ph6nkgqr3nppkg86fxaymg", + Weight: sdk.NewDecWithPrec(2, 1), + }, + { + ValOperAddress: "osmovaloper1jcr68jghzm24zwe78zuhz7xahua8429erxk7vm", + Weight: sdk.NewDecWithPrec(2, 1), + }, + { + ValOperAddress: "osmovaloper1gqsr38e4zteekwr6kq5se5jpadafqmcfyz8jds", + Weight: sdk.NewDecWithPrec(2, 1), + }, + }, + }, + expectPass: false, + }, } for _, test := range tests { diff --git a/x/validator-preference/types/state.pb.go b/x/valset-pref/types/state.pb.go similarity index 82% rename from x/validator-preference/types/state.pb.go rename to x/valset-pref/types/state.pb.go index 467994f7447..0874415d570 100644 --- a/x/validator-preference/types/state.pb.go +++ b/x/valset-pref/types/state.pb.go @@ -1,5 +1,5 @@ // Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: osmosis/validator-preference/v1beta1/state.proto +// source: osmosis/valset-pref/v1beta1/state.proto package types @@ -42,7 +42,7 @@ func (m *ValidatorPreference) Reset() { *m = ValidatorPreference{} } func (m *ValidatorPreference) String() string { return proto.CompactTextString(m) } func (*ValidatorPreference) ProtoMessage() {} func (*ValidatorPreference) Descriptor() ([]byte, []int) { - return fileDescriptor_2f4199f1be974865, []int{0} + return fileDescriptor_d3010474a5b89fce, []int{0} } func (m *ValidatorPreference) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -84,7 +84,7 @@ func (m *ValidatorSetPreferences) Reset() { *m = ValidatorSetPreferences func (m *ValidatorSetPreferences) String() string { return proto.CompactTextString(m) } func (*ValidatorSetPreferences) ProtoMessage() {} func (*ValidatorSetPreferences) Descriptor() ([]byte, []int) { - return fileDescriptor_2f4199f1be974865, []int{1} + return fileDescriptor_d3010474a5b89fce, []int{1} } func (m *ValidatorSetPreferences) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -114,39 +114,39 @@ func (m *ValidatorSetPreferences) XXX_DiscardUnknown() { var xxx_messageInfo_ValidatorSetPreferences proto.InternalMessageInfo func init() { - proto.RegisterType((*ValidatorPreference)(nil), "osmosis.validatorpreference.v1beta1.ValidatorPreference") - proto.RegisterType((*ValidatorSetPreferences)(nil), "osmosis.validatorpreference.v1beta1.ValidatorSetPreferences") + proto.RegisterType((*ValidatorPreference)(nil), "osmosis.valsetpref.v1beta1.ValidatorPreference") + proto.RegisterType((*ValidatorSetPreferences)(nil), "osmosis.valsetpref.v1beta1.ValidatorSetPreferences") } func init() { - proto.RegisterFile("osmosis/validator-preference/v1beta1/state.proto", fileDescriptor_2f4199f1be974865) + proto.RegisterFile("osmosis/valset-pref/v1beta1/state.proto", fileDescriptor_d3010474a5b89fce) } -var fileDescriptor_2f4199f1be974865 = []byte{ - // 358 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x92, 0x41, 0x4b, 0xfb, 0x30, - 0x18, 0xc6, 0x9b, 0xfd, 0x61, 0xf0, 0xef, 0x40, 0xa4, 0x0a, 0x1b, 0x53, 0xd2, 0x51, 0x41, 0x76, - 0x59, 0xe2, 0xe6, 0x45, 0x3c, 0xe9, 0x50, 0xaf, 0xca, 0x04, 0x0f, 0x1e, 0x1c, 0x69, 0xfb, 0xda, - 0x15, 0xbb, 0xa6, 0x24, 0xb1, 0xba, 0x6f, 0xa1, 0xdf, 0xc1, 0x0f, 0xb3, 0xe3, 0x8e, 0xe2, 0xa1, - 0xe8, 0xf6, 0x0d, 0xf6, 0x09, 0x64, 0x6d, 0xed, 0x86, 0xec, 0xe0, 0x29, 0x21, 0x79, 0x7f, 0x4f, - 0x9e, 0xe7, 0x7d, 0xa3, 0x1f, 0x70, 0x39, 0xe4, 0xd2, 0x97, 0x34, 0x66, 0x81, 0xef, 0x32, 0xc5, - 0x45, 0x2b, 0x12, 0x70, 0x0f, 0x02, 0x42, 0x07, 0x68, 0xdc, 0xb6, 0x41, 0xb1, 0x36, 0x95, 0x8a, - 0x29, 0x20, 0x91, 0xe0, 0x8a, 0x1b, 0x7b, 0x39, 0x41, 0x0a, 0x62, 0x09, 0x90, 0x1c, 0xa8, 0x6f, - 0x7b, 0xdc, 0xe3, 0x69, 0x3d, 0x5d, 0xec, 0x32, 0xb4, 0xbe, 0xeb, 0x71, 0xee, 0x05, 0x40, 0x59, - 0xe4, 0x53, 0x16, 0x86, 0x5c, 0x31, 0xe5, 0xf3, 0x50, 0x66, 0xb7, 0xd6, 0x1b, 0xd2, 0xb7, 0x6e, - 0x7e, 0x34, 0xaf, 0x0a, 0x4d, 0xe3, 0x5c, 0xdf, 0x8c, 0x59, 0xd0, 0xe7, 0x11, 0x88, 0x3e, 0x73, - 0x5d, 0x01, 0x52, 0xd6, 0x50, 0x03, 0x35, 0xff, 0x77, 0x77, 0xe6, 0x89, 0x59, 0x1d, 0xb1, 0x61, - 0x70, 0x6c, 0xfd, 0xae, 0xb0, 0x7a, 0x1b, 0x31, 0x0b, 0x2e, 0x23, 0x10, 0xa7, 0xd9, 0x81, 0x71, - 0xa1, 0x97, 0x9f, 0xc0, 0xf7, 0x06, 0xaa, 0x56, 0x4a, 0x61, 0x32, 0x4e, 0x4c, 0xed, 0x23, 0x31, - 0xf7, 0x3d, 0x5f, 0x0d, 0x1e, 0x6d, 0xe2, 0xf0, 0x21, 0x75, 0xd2, 0x6c, 0xf9, 0xd2, 0x92, 0xee, - 0x03, 0x55, 0xa3, 0x08, 0x24, 0x39, 0x03, 0xa7, 0x97, 0xd3, 0xd6, 0x2b, 0xd2, 0xab, 0x85, 0xcd, - 0x6b, 0x50, 0x4b, 0xa7, 0xd2, 0x88, 0xf5, 0xca, 0xb2, 0x19, 0xb2, 0x56, 0x6a, 0xfc, 0x6b, 0x56, - 0x3a, 0x47, 0xe4, 0x0f, 0x1d, 0x23, 0x6b, 0x92, 0x77, 0xeb, 0x0b, 0x8b, 0xf3, 0xc4, 0x34, 0xb2, - 0x8c, 0x2b, 0xd2, 0x56, 0x6f, 0xf5, 0xa1, 0xee, 0xdd, 0xf8, 0x0b, 0x6b, 0xe3, 0x29, 0x46, 0x93, - 0x29, 0x46, 0x9f, 0x53, 0x8c, 0x5e, 0x66, 0x58, 0x9b, 0xcc, 0xb0, 0xf6, 0x3e, 0xc3, 0xda, 0xed, - 0xc9, 0x4a, 0xc2, 0xdc, 0x4a, 0x2b, 0x60, 0xb6, 0xa4, 0xc5, 0xec, 0xdb, 0x1d, 0xfa, 0xbc, 0xfe, - 0x07, 0xa4, 0xf9, 0xed, 0x72, 0x3a, 0xa1, 0xc3, 0xef, 0x00, 0x00, 0x00, 0xff, 0xff, 0x10, 0xdc, - 0x3d, 0x1c, 0x2e, 0x02, 0x00, 0x00, +var fileDescriptor_d3010474a5b89fce = []byte{ + // 355 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x91, 0xcf, 0x4a, 0xeb, 0x40, + 0x18, 0xc5, 0x93, 0x5e, 0x28, 0xdc, 0x14, 0x44, 0xa2, 0xd0, 0x12, 0x25, 0x29, 0x59, 0x68, 0x37, + 0x9d, 0xa1, 0x75, 0x21, 0xb8, 0xb3, 0xa8, 0x5b, 0xa5, 0xa2, 0x0b, 0x37, 0x65, 0x92, 0x7c, 0x4d, + 0x83, 0x93, 0xcc, 0x30, 0x33, 0x46, 0xfb, 0x06, 0x2e, 0x7d, 0x08, 0x1f, 0xa6, 0xcb, 0x2e, 0xc5, + 0x45, 0xd0, 0xf6, 0x0d, 0xfa, 0x04, 0xd2, 0x24, 0xb4, 0x55, 0x74, 0x35, 0xff, 0x7e, 0xe7, 0xe3, + 0x9c, 0x39, 0xc6, 0x21, 0x93, 0x31, 0x93, 0x91, 0xc4, 0x29, 0xa1, 0x12, 0x54, 0x9b, 0x0b, 0x18, + 0xe2, 0xb4, 0xe3, 0x81, 0x22, 0x1d, 0x2c, 0x15, 0x51, 0x80, 0xb8, 0x60, 0x8a, 0x99, 0x56, 0x09, + 0xa2, 0x02, 0x5c, 0x72, 0xa8, 0xe4, 0xac, 0xdd, 0x90, 0x85, 0x2c, 0xc7, 0xf0, 0x72, 0x57, 0x28, + 0xac, 0xfd, 0x90, 0xb1, 0x90, 0x02, 0x26, 0x3c, 0xc2, 0x24, 0x49, 0x98, 0x22, 0x2a, 0x62, 0x89, + 0x2c, 0x5e, 0xdd, 0x57, 0xdd, 0xd8, 0xb9, 0x25, 0x34, 0x0a, 0x88, 0x62, 0xe2, 0x4a, 0xc0, 0x10, + 0x04, 0x24, 0x3e, 0x98, 0xe7, 0xc6, 0x76, 0x4a, 0xe8, 0x80, 0x71, 0x10, 0x03, 0x12, 0x04, 0x02, + 0xa4, 0x6c, 0xe8, 0x4d, 0xbd, 0xf5, 0xbf, 0xb7, 0xb7, 0xc8, 0x9c, 0xfa, 0x98, 0xc4, 0xf4, 0xc4, + 0xfd, 0x49, 0xb8, 0xfd, 0xad, 0x94, 0xd0, 0x4b, 0x0e, 0xe2, 0xb4, 0xb8, 0x30, 0x2f, 0x8c, 0xea, + 0x23, 0x44, 0xe1, 0x48, 0x35, 0x2a, 0xb9, 0x18, 0x4d, 0x32, 0x47, 0x7b, 0xcf, 0x9c, 0x83, 0x30, + 0x52, 0xa3, 0x07, 0x0f, 0xf9, 0x2c, 0xc6, 0x7e, 0x1e, 0xa9, 0x5c, 0xda, 0x32, 0xb8, 0xc7, 0x6a, + 0xcc, 0x41, 0xa2, 0x33, 0xf0, 0xfb, 0xa5, 0xda, 0x7d, 0xd6, 0x8d, 0xfa, 0xca, 0xe6, 0x35, 0xa8, + 0xb5, 0x53, 0x69, 0xc6, 0x46, 0x8d, 0xaf, 0x8f, 0x8d, 0x4a, 0xf3, 0x5f, 0xab, 0xd6, 0xc5, 0xe8, + 0xef, 0x8f, 0x42, 0xbf, 0x04, 0xee, 0x59, 0x4b, 0x67, 0x8b, 0xcc, 0x31, 0x8b, 0x68, 0x1b, 0x13, + 0xdd, 0xfe, 0xe6, 0xfc, 0xde, 0xcd, 0xe4, 0xd3, 0xd6, 0x26, 0x33, 0x5b, 0x9f, 0xce, 0x6c, 0xfd, + 0x63, 0x66, 0xeb, 0x2f, 0x73, 0x5b, 0x9b, 0xce, 0x6d, 0xed, 0x6d, 0x6e, 0x6b, 0x77, 0xc7, 0x1b, + 0xc1, 0x4a, 0x07, 0x6d, 0x4a, 0x3c, 0x89, 0x57, 0x05, 0x77, 0xba, 0xf8, 0xe9, 0x5b, 0xcd, 0x79, + 0x5a, 0xaf, 0x9a, 0xf7, 0x71, 0xf4, 0x15, 0x00, 0x00, 0xff, 0xff, 0x6d, 0x8b, 0x26, 0x51, 0x0a, + 0x02, 0x00, 0x00, } func (m *ValidatorPreference) Marshal() (dAtA []byte, err error) { diff --git a/x/validator-preference/types/tx.pb.go b/x/valset-pref/types/tx.pb.go similarity index 89% rename from x/validator-preference/types/tx.pb.go rename to x/valset-pref/types/tx.pb.go index f1450087091..96bffff9b22 100644 --- a/x/validator-preference/types/tx.pb.go +++ b/x/valset-pref/types/tx.pb.go @@ -1,5 +1,5 @@ // Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: osmosis/validator-preference/v1beta1/tx.proto +// source: osmosis/valset-pref/v1beta1/tx.proto package types @@ -41,7 +41,7 @@ func (m *MsgSetValidatorSetPreference) Reset() { *m = MsgSetValidatorSet func (m *MsgSetValidatorSetPreference) String() string { return proto.CompactTextString(m) } func (*MsgSetValidatorSetPreference) ProtoMessage() {} func (*MsgSetValidatorSetPreference) Descriptor() ([]byte, []int) { - return fileDescriptor_fa9fa79f914b826d, []int{0} + return fileDescriptor_daa95be02b2fc560, []int{0} } func (m *MsgSetValidatorSetPreference) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -91,7 +91,7 @@ func (m *MsgSetValidatorSetPreferenceResponse) Reset() { *m = MsgSetVali func (m *MsgSetValidatorSetPreferenceResponse) String() string { return proto.CompactTextString(m) } func (*MsgSetValidatorSetPreferenceResponse) ProtoMessage() {} func (*MsgSetValidatorSetPreferenceResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_fa9fa79f914b826d, []int{1} + return fileDescriptor_daa95be02b2fc560, []int{1} } func (m *MsgSetValidatorSetPreferenceResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -136,7 +136,7 @@ func (m *MsgDelegateToValidatorSet) Reset() { *m = MsgDelegateToValidato func (m *MsgDelegateToValidatorSet) String() string { return proto.CompactTextString(m) } func (*MsgDelegateToValidatorSet) ProtoMessage() {} func (*MsgDelegateToValidatorSet) Descriptor() ([]byte, []int) { - return fileDescriptor_fa9fa79f914b826d, []int{2} + return fileDescriptor_daa95be02b2fc560, []int{2} } func (m *MsgDelegateToValidatorSet) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -186,7 +186,7 @@ func (m *MsgDelegateToValidatorSetResponse) Reset() { *m = MsgDelegateTo func (m *MsgDelegateToValidatorSetResponse) String() string { return proto.CompactTextString(m) } func (*MsgDelegateToValidatorSetResponse) ProtoMessage() {} func (*MsgDelegateToValidatorSetResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_fa9fa79f914b826d, []int{3} + return fileDescriptor_daa95be02b2fc560, []int{3} } func (m *MsgDelegateToValidatorSetResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -230,7 +230,7 @@ func (m *MsgUndelegateFromValidatorSet) Reset() { *m = MsgUndelegateFrom func (m *MsgUndelegateFromValidatorSet) String() string { return proto.CompactTextString(m) } func (*MsgUndelegateFromValidatorSet) ProtoMessage() {} func (*MsgUndelegateFromValidatorSet) Descriptor() ([]byte, []int) { - return fileDescriptor_fa9fa79f914b826d, []int{4} + return fileDescriptor_daa95be02b2fc560, []int{4} } func (m *MsgUndelegateFromValidatorSet) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -280,7 +280,7 @@ func (m *MsgUndelegateFromValidatorSetResponse) Reset() { *m = MsgUndele func (m *MsgUndelegateFromValidatorSetResponse) String() string { return proto.CompactTextString(m) } func (*MsgUndelegateFromValidatorSetResponse) ProtoMessage() {} func (*MsgUndelegateFromValidatorSetResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_fa9fa79f914b826d, []int{5} + return fileDescriptor_daa95be02b2fc560, []int{5} } func (m *MsgUndelegateFromValidatorSetResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -320,7 +320,7 @@ func (m *MsgWithdrawDelegationRewards) Reset() { *m = MsgWithdrawDelegat func (m *MsgWithdrawDelegationRewards) String() string { return proto.CompactTextString(m) } func (*MsgWithdrawDelegationRewards) ProtoMessage() {} func (*MsgWithdrawDelegationRewards) Descriptor() ([]byte, []int) { - return fileDescriptor_fa9fa79f914b826d, []int{6} + return fileDescriptor_daa95be02b2fc560, []int{6} } func (m *MsgWithdrawDelegationRewards) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -363,7 +363,7 @@ func (m *MsgWithdrawDelegationRewardsResponse) Reset() { *m = MsgWithdra func (m *MsgWithdrawDelegationRewardsResponse) String() string { return proto.CompactTextString(m) } func (*MsgWithdrawDelegationRewardsResponse) ProtoMessage() {} func (*MsgWithdrawDelegationRewardsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_fa9fa79f914b826d, []int{7} + return fileDescriptor_daa95be02b2fc560, []int{7} } func (m *MsgWithdrawDelegationRewardsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -393,55 +393,55 @@ func (m *MsgWithdrawDelegationRewardsResponse) XXX_DiscardUnknown() { var xxx_messageInfo_MsgWithdrawDelegationRewardsResponse proto.InternalMessageInfo func init() { - proto.RegisterType((*MsgSetValidatorSetPreference)(nil), "osmosis.validatorpreference.v1beta1.MsgSetValidatorSetPreference") - proto.RegisterType((*MsgSetValidatorSetPreferenceResponse)(nil), "osmosis.validatorpreference.v1beta1.MsgSetValidatorSetPreferenceResponse") - proto.RegisterType((*MsgDelegateToValidatorSet)(nil), "osmosis.validatorpreference.v1beta1.MsgDelegateToValidatorSet") - proto.RegisterType((*MsgDelegateToValidatorSetResponse)(nil), "osmosis.validatorpreference.v1beta1.MsgDelegateToValidatorSetResponse") - proto.RegisterType((*MsgUndelegateFromValidatorSet)(nil), "osmosis.validatorpreference.v1beta1.MsgUndelegateFromValidatorSet") - proto.RegisterType((*MsgUndelegateFromValidatorSetResponse)(nil), "osmosis.validatorpreference.v1beta1.MsgUndelegateFromValidatorSetResponse") - proto.RegisterType((*MsgWithdrawDelegationRewards)(nil), "osmosis.validatorpreference.v1beta1.MsgWithdrawDelegationRewards") - proto.RegisterType((*MsgWithdrawDelegationRewardsResponse)(nil), "osmosis.validatorpreference.v1beta1.MsgWithdrawDelegationRewardsResponse") + proto.RegisterType((*MsgSetValidatorSetPreference)(nil), "osmosis.valsetpref.v1beta1.MsgSetValidatorSetPreference") + proto.RegisterType((*MsgSetValidatorSetPreferenceResponse)(nil), "osmosis.valsetpref.v1beta1.MsgSetValidatorSetPreferenceResponse") + proto.RegisterType((*MsgDelegateToValidatorSet)(nil), "osmosis.valsetpref.v1beta1.MsgDelegateToValidatorSet") + proto.RegisterType((*MsgDelegateToValidatorSetResponse)(nil), "osmosis.valsetpref.v1beta1.MsgDelegateToValidatorSetResponse") + proto.RegisterType((*MsgUndelegateFromValidatorSet)(nil), "osmosis.valsetpref.v1beta1.MsgUndelegateFromValidatorSet") + proto.RegisterType((*MsgUndelegateFromValidatorSetResponse)(nil), "osmosis.valsetpref.v1beta1.MsgUndelegateFromValidatorSetResponse") + proto.RegisterType((*MsgWithdrawDelegationRewards)(nil), "osmosis.valsetpref.v1beta1.MsgWithdrawDelegationRewards") + proto.RegisterType((*MsgWithdrawDelegationRewardsResponse)(nil), "osmosis.valsetpref.v1beta1.MsgWithdrawDelegationRewardsResponse") } func init() { - proto.RegisterFile("osmosis/validator-preference/v1beta1/tx.proto", fileDescriptor_fa9fa79f914b826d) + proto.RegisterFile("osmosis/valset-pref/v1beta1/tx.proto", fileDescriptor_daa95be02b2fc560) } -var fileDescriptor_fa9fa79f914b826d = []byte{ +var fileDescriptor_daa95be02b2fc560 = []byte{ // 530 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x55, 0x4f, 0x8b, 0xd3, 0x40, - 0x1c, 0xed, 0x6c, 0x55, 0xd8, 0xe9, 0x45, 0xc2, 0x22, 0x6d, 0xd0, 0xb4, 0x66, 0xd5, 0xed, 0xa5, - 0x19, 0x1b, 0x2f, 0xe2, 0x41, 0x34, 0xca, 0x82, 0x42, 0x41, 0xb2, 0xfe, 0x81, 0x3d, 0x08, 0x93, - 0x66, 0xcc, 0x06, 0xdb, 0x4c, 0xc9, 0x6f, 0xec, 0xee, 0x7e, 0x0b, 0x3f, 0x82, 0x57, 0x45, 0xd8, - 0x83, 0x5f, 0x62, 0xf1, 0xb4, 0x47, 0x4f, 0x55, 0xda, 0x6f, 0xb0, 0x9f, 0x40, 0x92, 0x4c, 0x27, - 0x3d, 0x6c, 0x6a, 0x68, 0xdd, 0x53, 0x0b, 0xf3, 0x7b, 0xef, 0xf7, 0x5e, 0xde, 0x1b, 0x06, 0x77, - 0x38, 0x0c, 0x39, 0x84, 0x40, 0xc6, 0x74, 0x10, 0xfa, 0x54, 0xf0, 0xb8, 0x33, 0x8a, 0xd9, 0x07, - 0x16, 0xb3, 0xa8, 0xcf, 0xc8, 0xb8, 0xeb, 0x31, 0x41, 0xbb, 0x44, 0x1c, 0x59, 0xa3, 0x98, 0x0b, - 0xae, 0x6d, 0xcb, 0x71, 0x4b, 0x8d, 0xe7, 0xd3, 0x96, 0x9c, 0xd6, 0xb7, 0x02, 0x1e, 0xf0, 0x74, - 0x9e, 0x24, 0xff, 0x32, 0xa8, 0x6e, 0xf4, 0x53, 0x2c, 0xf1, 0x28, 0xe4, 0xc4, 0x7d, 0x1e, 0x46, - 0xf2, 0xfc, 0x7e, 0x29, 0x25, 0x20, 0xa8, 0x60, 0x19, 0xc2, 0xfc, 0x89, 0xf0, 0xcd, 0x1e, 0x04, - 0x7b, 0x4c, 0xbc, 0x9d, 0x43, 0xf6, 0x98, 0x78, 0xa5, 0x40, 0x9a, 0x8d, 0x37, 0x7d, 0x36, 0x60, - 0x41, 0x72, 0x52, 0x47, 0x2d, 0xd4, 0xde, 0x74, 0xb6, 0xce, 0x27, 0xcd, 0xeb, 0xc7, 0x74, 0x38, - 0x78, 0x64, 0xaa, 0x23, 0xd3, 0xcd, 0xc7, 0xb4, 0x31, 0xae, 0xe5, 0x6b, 0xa1, 0xbe, 0xd1, 0xaa, - 0xb6, 0x6b, 0xf6, 0x43, 0xab, 0x84, 0x6f, 0x4b, 0xa9, 0xc8, 0x25, 0x38, 0xfa, 0xe9, 0xa4, 0x59, - 0x39, 0x9f, 0x34, 0xb5, 0x6c, 0xe7, 0x02, 0xb5, 0xe9, 0x2e, 0x2e, 0x32, 0xef, 0xe1, 0x3b, 0xcb, - 0xbc, 0xb8, 0x0c, 0x46, 0x3c, 0x02, 0x66, 0x9e, 0x20, 0xdc, 0xe8, 0x41, 0xf0, 0x3c, 0x13, 0xcc, - 0x5e, 0xf3, 0xc5, 0xf9, 0x95, 0x1c, 0xbf, 0xc7, 0x57, 0x92, 0x18, 0xea, 0x1b, 0x2d, 0xd4, 0xae, - 0xd9, 0x0d, 0x2b, 0xcb, 0xc9, 0x4a, 0x72, 0x52, 0xd6, 0x9e, 0xf1, 0x30, 0x72, 0x48, 0xe2, 0xe5, - 0xdb, 0xef, 0xe6, 0x4e, 0x10, 0x8a, 0x83, 0x4f, 0x9e, 0xd5, 0xe7, 0x43, 0x22, 0x43, 0xcd, 0x7e, - 0x3a, 0xe0, 0x7f, 0x24, 0xe2, 0x78, 0xc4, 0x20, 0x05, 0xb8, 0x29, 0xaf, 0xb9, 0x8d, 0x6f, 0x17, - 0x0a, 0x56, 0xb6, 0x7e, 0x20, 0x7c, 0xab, 0x07, 0xc1, 0x9b, 0x48, 0xea, 0x62, 0xbb, 0x31, 0x1f, - 0xfe, 0x37, 0x6b, 0xd5, 0x4b, 0xb2, 0xb6, 0x83, 0xef, 0x2e, 0x15, 0xad, 0xec, 0xb9, 0x69, 0x53, - 0xdf, 0x85, 0xe2, 0xc0, 0x8f, 0xe9, 0xa1, 0xfc, 0x16, 0x21, 0x8f, 0x5c, 0x76, 0x48, 0x63, 0x1f, - 0x56, 0x31, 0x27, 0x1b, 0x53, 0xc8, 0x39, 0xdf, 0x6d, 0x9f, 0x5c, 0xc5, 0xd5, 0x1e, 0x04, 0xda, - 0x57, 0x84, 0x1b, 0xc5, 0x77, 0xe5, 0x69, 0xa9, 0x8a, 0x2f, 0xab, 0xa8, 0xfe, 0x62, 0x6d, 0x8a, - 0xb9, 0x66, 0xed, 0x0b, 0xc2, 0x37, 0x0a, 0x2a, 0xfe, 0xb8, 0xec, 0x96, 0x8b, 0xf1, 0xfa, 0xee, - 0x7a, 0x78, 0x25, 0xf1, 0x3b, 0xc2, 0xfa, 0x92, 0xba, 0x3a, 0x65, 0xd7, 0x14, 0x73, 0xe8, 0x2f, - 0xd7, 0xe7, 0x50, 0x72, 0x93, 0xf4, 0x8b, 0xfb, 0x57, 0x3a, 0xfd, 0x42, 0x8a, 0xf2, 0xe9, 0xff, - 0xb3, 0xb1, 0xce, 0xfe, 0xe9, 0xd4, 0x40, 0x67, 0x53, 0x03, 0xfd, 0x99, 0x1a, 0xe8, 0xf3, 0xcc, - 0xa8, 0x9c, 0xcd, 0x8c, 0xca, 0xaf, 0x99, 0x51, 0xd9, 0x7f, 0xb2, 0x70, 0x3f, 0xe5, 0xba, 0xce, - 0x80, 0x7a, 0x40, 0xd4, 0xe3, 0xd1, 0xb5, 0xc9, 0xd1, 0xc5, 0x4f, 0x48, 0x7a, 0x7b, 0xbd, 0x6b, - 0xe9, 0xdb, 0xf1, 0xe0, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xcf, 0x83, 0x26, 0x47, 0xf9, 0x06, + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x54, 0x4d, 0x8b, 0xd3, 0x40, + 0x18, 0xee, 0x6c, 0x17, 0x61, 0xa7, 0x17, 0x09, 0x8b, 0xb4, 0x41, 0xd3, 0x1a, 0x57, 0xdb, 0x4b, + 0x33, 0x34, 0x22, 0x7e, 0x80, 0xa0, 0x55, 0xbc, 0x15, 0x34, 0xeb, 0x07, 0x78, 0x10, 0x26, 0xcd, + 0xbb, 0xd9, 0x60, 0x92, 0x09, 0x99, 0x71, 0x3f, 0xfe, 0x84, 0x78, 0x13, 0xfc, 0x09, 0x5e, 0x3c, + 0xf8, 0x0b, 0xbc, 0xed, 0x71, 0x8f, 0x9e, 0xaa, 0xb4, 0x07, 0xef, 0xfb, 0x0b, 0x24, 0x1f, 0x3b, + 0x8d, 0x60, 0x12, 0x08, 0x7a, 0x6a, 0x61, 0x9e, 0xe7, 0x79, 0x9f, 0x27, 0xef, 0x33, 0x83, 0x77, + 0x18, 0x0f, 0x18, 0xf7, 0x38, 0x39, 0xa0, 0x3e, 0x07, 0x31, 0x8e, 0x62, 0xd8, 0x23, 0x07, 0x13, + 0x1b, 0x04, 0x9d, 0x10, 0x71, 0x64, 0x44, 0x31, 0x13, 0x4c, 0x51, 0x73, 0x94, 0x91, 0xa1, 0x12, + 0x90, 0x91, 0x83, 0xd4, 0x6d, 0x97, 0xb9, 0x2c, 0x85, 0x91, 0xe4, 0x5f, 0xc6, 0x50, 0xb5, 0x79, + 0x4a, 0x21, 0x36, 0xe5, 0x20, 0xf5, 0xe6, 0xcc, 0x0b, 0xf3, 0xf3, 0x61, 0xd5, 0x5c, 0x2e, 0xa8, + 0x80, 0x0c, 0xa8, 0x7f, 0x43, 0xf8, 0xf2, 0x8c, 0xbb, 0xbb, 0x20, 0x5e, 0x52, 0xdf, 0x73, 0xa8, + 0x60, 0xf1, 0x2e, 0x88, 0xa7, 0x31, 0xec, 0x41, 0x0c, 0xe1, 0x1c, 0x14, 0x13, 0x6f, 0x39, 0xe0, + 0x83, 0x9b, 0x9c, 0x74, 0xd1, 0x00, 0x8d, 0xb6, 0xa6, 0xdb, 0x67, 0x8b, 0xfe, 0xc5, 0x63, 0x1a, + 0xf8, 0xf7, 0x74, 0x79, 0xa4, 0x5b, 0x6b, 0x98, 0x12, 0xe0, 0x4e, 0x24, 0x15, 0x78, 0x77, 0x63, + 0xd0, 0x1e, 0x75, 0x4c, 0x62, 0x94, 0xa7, 0x34, 0xe4, 0xf0, 0xf5, 0xe4, 0xa9, 0x7a, 0xb2, 0xe8, + 0xb7, 0xce, 0x16, 0x7d, 0x25, 0x1b, 0x55, 0x50, 0xd4, 0xad, 0xa2, 0xbe, 0x7e, 0x03, 0xef, 0x54, + 0x45, 0xb0, 0x80, 0x47, 0x2c, 0xe4, 0xa0, 0x7f, 0x41, 0xb8, 0x37, 0xe3, 0xee, 0xe3, 0xcc, 0x27, + 0x3c, 0x67, 0x45, 0x7c, 0xa3, 0xa0, 0x6f, 0xf0, 0x66, 0xf2, 0xd1, 0xbb, 0x1b, 0x03, 0x34, 0xea, + 0x98, 0x3d, 0x23, 0xdb, 0x8a, 0x91, 0x6c, 0x45, 0x46, 0x7b, 0xc4, 0xbc, 0x70, 0x4a, 0x92, 0x2c, + 0x9f, 0x7f, 0xf4, 0x87, 0xae, 0x27, 0xf6, 0xdf, 0xd9, 0xc6, 0x9c, 0x05, 0x24, 0x5f, 0x61, 0xf6, + 0x33, 0xe6, 0xce, 0x5b, 0x22, 0x8e, 0x23, 0xe0, 0x29, 0xc1, 0x4a, 0x75, 0xf5, 0x6b, 0xf8, 0x6a, + 0xa9, 0x61, 0x19, 0xeb, 0x2b, 0xc2, 0x57, 0x66, 0xdc, 0x7d, 0x11, 0xe6, 0xbe, 0xe0, 0x49, 0xcc, + 0x82, 0x7f, 0x16, 0xad, 0xfd, 0x9f, 0xa2, 0x0d, 0xf1, 0xf5, 0x4a, 0xd3, 0x32, 0x9e, 0x95, 0x16, + 0xf4, 0x95, 0x27, 0xf6, 0x9d, 0x98, 0x1e, 0xe6, 0xdf, 0xc2, 0x63, 0xa1, 0x05, 0x87, 0x34, 0x76, + 0x78, 0x93, 0x70, 0x79, 0x63, 0x4a, 0x35, 0xcf, 0x67, 0x9b, 0xbf, 0x36, 0x71, 0x7b, 0xc6, 0x5d, + 0xe5, 0x23, 0xc2, 0xbd, 0xf2, 0x2b, 0x72, 0xa7, 0xaa, 0xd9, 0x55, 0xcd, 0x54, 0x1f, 0x34, 0x65, + 0x9e, 0x3b, 0x54, 0xde, 0x23, 0x7c, 0xa9, 0xa4, 0xd0, 0xb7, 0x6a, 0xc4, 0xff, 0x4e, 0x53, 0xef, + 0x37, 0xa2, 0x49, 0x43, 0x9f, 0x10, 0x56, 0x2b, 0xaa, 0x78, 0xb7, 0x46, 0xbd, 0x9c, 0xaa, 0x3e, + 0x6c, 0x4c, 0x95, 0xe6, 0x92, 0x3d, 0x96, 0x37, 0xa9, 0x6e, 0x8f, 0xa5, 0xcc, 0xda, 0x3d, 0xd6, + 0x36, 0x6d, 0xfa, 0xec, 0x64, 0xa9, 0xa1, 0xd3, 0xa5, 0x86, 0x7e, 0x2e, 0x35, 0xf4, 0x61, 0xa5, + 0xb5, 0x4e, 0x57, 0x5a, 0xeb, 0xfb, 0x4a, 0x6b, 0xbd, 0xbe, 0x5d, 0xb8, 0x57, 0xf9, 0x94, 0xb1, + 0x4f, 0x6d, 0x4e, 0xe4, 0x13, 0x3f, 0x31, 0xc9, 0xd1, 0x1f, 0x0f, 0x7d, 0x7a, 0xd9, 0xec, 0x0b, + 0xe9, 0x0b, 0x7f, 0xf3, 0x77, 0x00, 0x00, 0x00, 0xff, 0xff, 0x0a, 0x1f, 0xbc, 0x17, 0x84, 0x06, 0x00, 0x00, } @@ -482,7 +482,7 @@ func NewMsgClient(cc grpc1.ClientConn) MsgClient { func (c *msgClient) SetValidatorSetPreference(ctx context.Context, in *MsgSetValidatorSetPreference, opts ...grpc.CallOption) (*MsgSetValidatorSetPreferenceResponse, error) { out := new(MsgSetValidatorSetPreferenceResponse) - err := c.cc.Invoke(ctx, "/osmosis.validatorpreference.v1beta1.Msg/SetValidatorSetPreference", in, out, opts...) + err := c.cc.Invoke(ctx, "/osmosis.valsetpref.v1beta1.Msg/SetValidatorSetPreference", in, out, opts...) if err != nil { return nil, err } @@ -491,7 +491,7 @@ func (c *msgClient) SetValidatorSetPreference(ctx context.Context, in *MsgSetVal func (c *msgClient) DelegateToValidatorSet(ctx context.Context, in *MsgDelegateToValidatorSet, opts ...grpc.CallOption) (*MsgDelegateToValidatorSetResponse, error) { out := new(MsgDelegateToValidatorSetResponse) - err := c.cc.Invoke(ctx, "/osmosis.validatorpreference.v1beta1.Msg/DelegateToValidatorSet", in, out, opts...) + err := c.cc.Invoke(ctx, "/osmosis.valsetpref.v1beta1.Msg/DelegateToValidatorSet", in, out, opts...) if err != nil { return nil, err } @@ -500,7 +500,7 @@ func (c *msgClient) DelegateToValidatorSet(ctx context.Context, in *MsgDelegateT func (c *msgClient) UndelegateFromValidatorSet(ctx context.Context, in *MsgUndelegateFromValidatorSet, opts ...grpc.CallOption) (*MsgUndelegateFromValidatorSetResponse, error) { out := new(MsgUndelegateFromValidatorSetResponse) - err := c.cc.Invoke(ctx, "/osmosis.validatorpreference.v1beta1.Msg/UndelegateFromValidatorSet", in, out, opts...) + err := c.cc.Invoke(ctx, "/osmosis.valsetpref.v1beta1.Msg/UndelegateFromValidatorSet", in, out, opts...) if err != nil { return nil, err } @@ -509,7 +509,7 @@ func (c *msgClient) UndelegateFromValidatorSet(ctx context.Context, in *MsgUndel func (c *msgClient) WithdrawDelegationRewards(ctx context.Context, in *MsgWithdrawDelegationRewards, opts ...grpc.CallOption) (*MsgWithdrawDelegationRewardsResponse, error) { out := new(MsgWithdrawDelegationRewardsResponse) - err := c.cc.Invoke(ctx, "/osmosis.validatorpreference.v1beta1.Msg/WithdrawDelegationRewards", in, out, opts...) + err := c.cc.Invoke(ctx, "/osmosis.valsetpref.v1beta1.Msg/WithdrawDelegationRewards", in, out, opts...) if err != nil { return nil, err } @@ -564,7 +564,7 @@ func _Msg_SetValidatorSetPreference_Handler(srv interface{}, ctx context.Context } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/osmosis.validatorpreference.v1beta1.Msg/SetValidatorSetPreference", + FullMethod: "/osmosis.valsetpref.v1beta1.Msg/SetValidatorSetPreference", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(MsgServer).SetValidatorSetPreference(ctx, req.(*MsgSetValidatorSetPreference)) @@ -582,7 +582,7 @@ func _Msg_DelegateToValidatorSet_Handler(srv interface{}, ctx context.Context, d } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/osmosis.validatorpreference.v1beta1.Msg/DelegateToValidatorSet", + FullMethod: "/osmosis.valsetpref.v1beta1.Msg/DelegateToValidatorSet", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(MsgServer).DelegateToValidatorSet(ctx, req.(*MsgDelegateToValidatorSet)) @@ -600,7 +600,7 @@ func _Msg_UndelegateFromValidatorSet_Handler(srv interface{}, ctx context.Contex } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/osmosis.validatorpreference.v1beta1.Msg/UndelegateFromValidatorSet", + FullMethod: "/osmosis.valsetpref.v1beta1.Msg/UndelegateFromValidatorSet", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(MsgServer).UndelegateFromValidatorSet(ctx, req.(*MsgUndelegateFromValidatorSet)) @@ -618,7 +618,7 @@ func _Msg_WithdrawDelegationRewards_Handler(srv interface{}, ctx context.Context } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/osmosis.validatorpreference.v1beta1.Msg/WithdrawDelegationRewards", + FullMethod: "/osmosis.valsetpref.v1beta1.Msg/WithdrawDelegationRewards", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(MsgServer).WithdrawDelegationRewards(ctx, req.(*MsgWithdrawDelegationRewards)) @@ -627,7 +627,7 @@ func _Msg_WithdrawDelegationRewards_Handler(srv interface{}, ctx context.Context } var _Msg_serviceDesc = grpc.ServiceDesc{ - ServiceName: "osmosis.validatorpreference.v1beta1.Msg", + ServiceName: "osmosis.valsetpref.v1beta1.Msg", HandlerType: (*MsgServer)(nil), Methods: []grpc.MethodDesc{ { @@ -648,7 +648,7 @@ var _Msg_serviceDesc = grpc.ServiceDesc{ }, }, Streams: []grpc.StreamDesc{}, - Metadata: "osmosis/validator-preference/v1beta1/tx.proto", + Metadata: "osmosis/valset-pref/v1beta1/tx.proto", } func (m *MsgSetValidatorSetPreference) Marshal() (dAtA []byte, err error) { diff --git a/x/validator-preference/validator_set.go b/x/valset-pref/validator_set.go similarity index 51% rename from x/validator-preference/validator_set.go rename to x/valset-pref/validator_set.go index d2c47675d5f..0973a30fd05 100644 --- a/x/validator-preference/validator_set.go +++ b/x/valset-pref/validator_set.go @@ -6,9 +6,29 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - "github.com/osmosis-labs/osmosis/v12/x/validator-preference/types" + "github.com/osmosis-labs/osmosis/v12/x/valset-pref/types" ) +func (k Keeper) SetupValidatorSetPreference(ctx sdk.Context, delegator string, preferences []types.ValidatorPreference) error { + // check if a user already has a validator-set created + existingValidators, found := k.GetValidatorSetPreference(ctx, delegator) + if found { + // check if the new preferences is the same as the existing preferences + isEqual := k.IsValidatorSetEqual(preferences, existingValidators.Preferences) + if isEqual { + return fmt.Errorf("The preferences (validator and weights) are the same") + } + } + + // checks that all the validators exist on chain + isValid := k.IsPreferenceValid(ctx, preferences) + if !isValid { + return fmt.Errorf("The validator preference list is not valid") + } + + return nil +} + // GetValAddrAndVal checks if the validator address is valid and the validator provided exists on chain. func (k Keeper) getValAddrAndVal(ctx sdk.Context, valOperAddress string) (sdk.ValAddress, stakingtypes.Validator, error) { valAddr, err := sdk.ValAddressFromBech32(valOperAddress) @@ -24,58 +44,46 @@ func (k Keeper) getValAddrAndVal(ctx sdk.Context, valOperAddress string) (sdk.Va return valAddr, validator, nil } -// ValidatePreferences loops through the validator preferences and checks its existence and validity. -func (k Keeper) ValidatePreferences(ctx sdk.Context, preferences []types.ValidatorPreference) error { +// IsPreferenceValid loops through the validator preferences and checks its existence and validity. +func (k Keeper) IsPreferenceValid(ctx sdk.Context, preferences []types.ValidatorPreference) bool { for _, val := range preferences { _, _, err := k.getValAddrAndVal(ctx, val.ValOperAddress) if err != nil { - return err + return false } } - return nil -} - -// ChargeForCreateValSet gets the creationFee (default 10osmo) and funds it to the community pool. -func (k Keeper) ChargeForCreateValSet(ctx sdk.Context, delegatorAddr string) error { - // Send creation fee to community pool - creationFee := k.GetParams(ctx).ValsetCreationFee - if creationFee == nil { - return fmt.Errorf("creation fee cannot be nil or 0 ") - } - - accAddr, err := sdk.AccAddressFromBech32(delegatorAddr) - if err != nil { - return err - } - - if err := k.distrKeeper.FundCommunityPool(ctx, creationFee, accAddr); err != nil { - return err - } - - return nil + return true } -// SortAndCompareValidatorSet returns true if the two preferences are equal -func (k Keeper) SortAndCompareValidatorSet(newPreferences, existingPreferences []types.ValidatorPreference) bool { +// IsValidatorSetEqual returns true if the two preferences are equal. +func (k Keeper) IsValidatorSetEqual(newPreferences, existingPreferences []types.ValidatorPreference) bool { + var isEqual bool + // check if the two validator-set length are equal if len(newPreferences) != len(existingPreferences) { return false } + // sort the new validator-set sort.Slice(newPreferences, func(i, j int) bool { return newPreferences[i].ValOperAddress < newPreferences[j].ValOperAddress }) + // sort the existing validator-set sort.Slice(existingPreferences, func(i, j int) bool { return existingPreferences[i].ValOperAddress < existingPreferences[j].ValOperAddress }) // make sure that both valAddress and weights cannot be the same in the new val-set + // if we just find one difference between two sets we can guarantee that they are different for i := range newPreferences { if newPreferences[i].ValOperAddress != existingPreferences[i].ValOperAddress || !newPreferences[i].Weight.Equal(existingPreferences[i].Weight) { - return false + isEqual = false + break + } else { + isEqual = true } } - return true + return isEqual } diff --git a/x/validator-preference/valpref-module/module.go b/x/valset-pref/valpref-module/module.go similarity index 83% rename from x/validator-preference/valpref-module/module.go rename to x/valset-pref/valpref-module/module.go index 7e5a5171700..0c5904fbf1a 100644 --- a/x/validator-preference/valpref-module/module.go +++ b/x/valset-pref/valpref-module/module.go @@ -1,6 +1,7 @@ package validator_preference import ( + "context" "encoding/json" "fmt" "math/rand" @@ -8,8 +9,8 @@ import ( "github.com/gorilla/mux" "github.com/grpc-ecosystem/grpc-gateway/runtime" - keeper "github.com/osmosis-labs/osmosis/v12/x/validator-preference" - "github.com/osmosis-labs/osmosis/v12/x/validator-preference/types" + keeper "github.com/osmosis-labs/osmosis/v12/x/valset-pref" + "github.com/osmosis-labs/osmosis/v12/x/valset-pref/types" "github.com/spf13/cobra" abci "github.com/tendermint/tendermint/abci/types" @@ -19,7 +20,8 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" simtypes "github.com/cosmos/cosmos-sdk/types/simulation" - stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + validatorprefclient "github.com/osmosis-labs/osmosis/v12/x/valset-pref/client" + "github.com/osmosis-labs/osmosis/v12/x/valset-pref/client/queryproto" ) var ( @@ -60,15 +62,11 @@ func (a AppModuleBasic) RegisterInterfaces(reg cdctypes.InterfaceRegistry) { // DefaultGenesis returns the capability module's default genesis state. func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage { - return cdc.MustMarshalJSON(types.DefaultGenesis()) + return nil } // ValidateGenesis performs genesis state validation for the capability module. func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, config client.TxEncodingConfig, bz json.RawMessage) error { - var genState types.GenesisState - if err := cdc.UnmarshalJSON(bz, &genState); err != nil { - return fmt.Errorf("failed to unmarshal %s genesis state: %w", types.ModuleName, err) - } return nil } @@ -78,6 +76,7 @@ func (AppModuleBasic) RegisterRESTRoutes(clientCtx client.Context, rtr *mux.Rout // RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the module. func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) { + queryproto.RegisterQueryHandlerClient(context.Background(), mux, queryproto.NewQueryClient(clientCtx)) //nolint:errcheck } // GetTxCmd returns the capability module's root tx command. @@ -98,21 +97,13 @@ func (AppModuleBasic) GetQueryCmd() *cobra.Command { type AppModule struct { AppModuleBasic - keeper keeper.Keeper - accountKeeper stakingtypes.AccountKeeper - bankKeeper stakingtypes.BankKeeper + keeper keeper.Keeper } -func NewAppModule(cdc codec.Codec, keeper keeper.Keeper, - accountKeeper stakingtypes.AccountKeeper, - bankKeeper stakingtypes.BankKeeper, -) AppModule { +func NewAppModule(cdc codec.Codec, keeper keeper.Keeper) AppModule { return AppModule{ AppModuleBasic: NewAppModuleBasic(cdc), keeper: keeper, - - accountKeeper: accountKeeper, - bankKeeper: bankKeeper, } } @@ -129,7 +120,7 @@ func (am AppModule) Route() sdk.Route { // QuerierRoute returns the capability module's query routing key. func (AppModule) QuerierRoute() string { return types.QuerierRoute } -// LegacyQuerierHandler returns the x/validator-preference module's Querier. +// LegacyQuerierHandler returns the x/valset-pref module's Querier. func (am AppModule) LegacyQuerierHandler(legacyQuerierCdc *codec.LegacyAmino) sdk.Querier { return func(sdk.Context, []string, abci.RequestQuery) ([]byte, error) { return nil, fmt.Errorf("legacy querier not supported for the x/%s module", types.ModuleName) @@ -138,6 +129,8 @@ func (am AppModule) LegacyQuerierHandler(legacyQuerierCdc *codec.LegacyAmino) sd // RegisterServices registers module services. func (am AppModule) RegisterServices(cfg module.Configurator) { + types.RegisterMsgServer(cfg.MsgServer(), keeper.NewMsgServerImpl(&am.keeper)) + queryproto.RegisterQueryServer(cfg.QueryServer(), validatorprefclient.NewQuerier(am.keeper)) } // RegisterInvariants registers the capability module's invariants. @@ -146,20 +139,13 @@ func (am AppModule) RegisterInvariants(ir sdk.InvariantRegistry) { // InitGenesis performs the capability module's genesis initialization It returns // no validator updates. -// TODO: implement this func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, gs json.RawMessage) []abci.ValidatorUpdate { - var genState types.GenesisState - // Initialize global index to index in genesis state - cdc.MustUnmarshalJSON(gs, &genState) - am.keeper.InitGenesis(ctx, genState) return []abci.ValidatorUpdate{} } // ExportGenesis returns the capability module's exported genesis state as raw JSON bytes. -// TODO: Come back and fix this func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawMessage { - genState := am.keeper.ExportGenesis(ctx) - return cdc.MustMarshalJSON(genState) + return nil } // BeginBlock executes all ABCI BeginBlock logic respective to the capability module. @@ -186,12 +172,11 @@ func (am AppModule) ProposalContents(simState module.SimulationState) []simtypes // RandomizedParams creates randomized pool-incentives param changes for the simulator. func (AppModule) RandomizedParams(r *rand.Rand) []simtypes.ParamChange { - return nil // TODO + return nil } // RegisterStoreDecoder registers a decoder for supply module's types. func (am AppModule) RegisterStoreDecoder(sdr sdk.StoreDecoderRegistry) { - // TODO } // WeightedOperations returns the all the module operations with their respective weights. From a3a55cc2d18793d3e4dfaea01ee2e7881951c929 Mon Sep 17 00:00:00 2001 From: stackman27 Date: Sat, 5 Nov 2022 14:58:40 -0700 Subject: [PATCH 3/3] bez feedback --- x/valset-pref/client/query_proto_wrap.go | 4 ++-- x/valset-pref/types/codec.go | 8 ++++---- x/valset-pref/types/keys.go | 3 --- x/valset-pref/types/msgs.go | 20 ++++++++------------ x/valset-pref/types/msgs_test.go | 1 - 5 files changed, 14 insertions(+), 22 deletions(-) diff --git a/x/valset-pref/client/query_proto_wrap.go b/x/valset-pref/client/query_proto_wrap.go index 401585539d9..8d597222851 100644 --- a/x/valset-pref/client/query_proto_wrap.go +++ b/x/valset-pref/client/query_proto_wrap.go @@ -8,13 +8,13 @@ import ( ) type Querier struct { - K validatorprefkeeper.Keeper + validatorprefkeeper.Keeper } var _ queryproto.QueryServer = Querier{} func NewQuerier(k validatorprefkeeper.Keeper) Querier { - return Querier{K: k} + return Querier{k} } func (q Querier) UserValidatorPreferences(ctx context.Context, req *queryproto.QueryUserValidatorPreferences) (*queryproto.QueryUserValidatorPreferenceResponse, error) { diff --git a/x/valset-pref/types/codec.go b/x/valset-pref/types/codec.go index 1c4b783cff4..995b19f8034 100644 --- a/x/valset-pref/types/codec.go +++ b/x/valset-pref/types/codec.go @@ -8,10 +8,10 @@ import ( ) func RegisterCodec(cdc *codec.LegacyAmino) { - cdc.RegisterConcrete(&MsgSetValidatorSetPreference{}, "osmosis/validator-set-preference/set-validator-set-preference", nil) - cdc.RegisterConcrete(&MsgDelegateToValidatorSet{}, "osmosis/validator-set-preference/delegate-to-validator-set", nil) - cdc.RegisterConcrete(&MsgUndelegateFromValidatorSet{}, "osmosis/validator-set-preference/undelegate-from-validator-set", nil) - cdc.RegisterConcrete(&MsgWithdrawDelegationRewards{}, "osmosis/validator-set-preference/withdraw-delegation-rewards", nil) + cdc.RegisterConcrete(&MsgSetValidatorSetPreference{}, "osmosis/valset-pref/MsgSetValidatorSetPreference", nil) + cdc.RegisterConcrete(&MsgDelegateToValidatorSet{}, "osmosis/valset-pref/MsgDelegateToValidatorSet", nil) + cdc.RegisterConcrete(&MsgUndelegateFromValidatorSet{}, "osmosis/valset-pref/MsgUndelegateFromValidatorSet", nil) + cdc.RegisterConcrete(&MsgWithdrawDelegationRewards{}, "osmosis/valset-pref/MsgWithdrawDelegationRewards", nil) } func RegisterInterfaces(registry cdctypes.InterfaceRegistry) { diff --git a/x/valset-pref/types/keys.go b/x/valset-pref/types/keys.go index f5c7cc78cbc..24347ccf83e 100644 --- a/x/valset-pref/types/keys.go +++ b/x/valset-pref/types/keys.go @@ -7,9 +7,6 @@ var ( // StoreKey defines the primary module store key StoreKey = ModuleName - // RouterKey is the message route for slashing. - RouterKey = ModuleName - // KeyPrefixValidatorSet defines prefix key for validator set. KeyPrefixValidatorSet = []byte{0x01} diff --git a/x/valset-pref/types/msgs.go b/x/valset-pref/types/msgs.go index 77b24a71eb6..d0288b35a8a 100644 --- a/x/valset-pref/types/msgs.go +++ b/x/valset-pref/types/msgs.go @@ -23,15 +23,14 @@ func NewMsgSetValidatorSetPreference(delegator sdk.AccAddress, preferences []Val } } -func (m MsgSetValidatorSetPreference) Route() string { return RouterKey } -func (m MsgSetValidatorSetPreference) Type() string { return TypeMsgSetValidatorSetPreference } +func (m MsgSetValidatorSetPreference) Type() string { return TypeMsgSetValidatorSetPreference } func (m MsgSetValidatorSetPreference) ValidateBasic() error { _, err := sdk.AccAddressFromBech32(m.Delegator) if err != nil { return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "Invalid delegator address (%s)", err) } - total_weight := sdk.NewDec(0) + totalWeight := sdk.ZeroDec() validatorAddrs := []string{} for _, validator := range m.Preferences { _, err := sdk.ValAddressFromBech32(validator.ValOperAddress) @@ -39,7 +38,7 @@ func (m MsgSetValidatorSetPreference) ValidateBasic() error { return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "Invalid validator address (%s)", err) } - total_weight = total_weight.Add(validator.Weight) + totalWeight = totalWeight.Add(validator.Weight) validatorAddrs = append(validatorAddrs, validator.ValOperAddress) } @@ -50,8 +49,8 @@ func (m MsgSetValidatorSetPreference) ValidateBasic() error { } // check if the total validator distribution weights equal 1 - if !total_weight.Equal(sdk.NewDec(1)) { - return fmt.Errorf("The weights allocated to the validators do not add up to 1, Got: %d", total_weight) + if !totalWeight.Equal(sdk.OneDec()) { + return fmt.Errorf("The weights allocated to the validators do not add up to 1, Got: %d", totalWeight) } return nil @@ -82,8 +81,7 @@ func NewMsgMsgStakeToValidatorSet(delegator sdk.AccAddress, coin sdk.Coin) *MsgD } } -func (m MsgDelegateToValidatorSet) Route() string { return RouterKey } -func (m MsgDelegateToValidatorSet) Type() string { return TypeMsgDelegateToValidatorSet } +func (m MsgDelegateToValidatorSet) Type() string { return TypeMsgDelegateToValidatorSet } func (m MsgDelegateToValidatorSet) ValidateBasic() error { _, err := sdk.AccAddressFromBech32(m.Delegator) if err != nil { @@ -121,8 +119,7 @@ func NewMsgUndelegateFromValidatorSet(delegator sdk.AccAddress, coin sdk.Coin) * } } -func (m MsgUndelegateFromValidatorSet) Route() string { return RouterKey } -func (m MsgUndelegateFromValidatorSet) Type() string { return TypeMsgUndelegateFromValidatorSet } +func (m MsgUndelegateFromValidatorSet) Type() string { return TypeMsgUndelegateFromValidatorSet } func (m MsgUndelegateFromValidatorSet) ValidateBasic() error { _, err := sdk.AccAddressFromBech32(m.Delegator) if err != nil { @@ -159,8 +156,7 @@ func NewMsgWithdrawDelegationRewards(delegator sdk.AccAddress) *MsgWithdrawDeleg } } -func (m MsgWithdrawDelegationRewards) Route() string { return RouterKey } -func (m MsgWithdrawDelegationRewards) Type() string { return TypeMsgWithdrawDelegationRewards } +func (m MsgWithdrawDelegationRewards) Type() string { return TypeMsgWithdrawDelegationRewards } func (m MsgWithdrawDelegationRewards) ValidateBasic() error { _, err := sdk.AccAddressFromBech32(m.Delegator) if err != nil { diff --git a/x/valset-pref/types/msgs_test.go b/x/valset-pref/types/msgs_test.go index 47e05da50cb..85456aca4b5 100644 --- a/x/valset-pref/types/msgs_test.go +++ b/x/valset-pref/types/msgs_test.go @@ -144,7 +144,6 @@ func TestMsgSetValidatorSetPreference(t *testing.T) { t.Run(test.name, func(t *testing.T) { if test.expectPass { require.NoError(t, test.msg.ValidateBasic(), "test: %v", test.name) - require.Equal(t, test.msg.Route(), types.RouterKey) require.Equal(t, test.msg.Type(), "set_validator_set_preference") signers := test.msg.GetSigners() require.Equal(t, len(signers), 1)