Skip to content

Commit

Permalink
feat: pool commission & stake fraction (#210)
Browse files Browse the repository at this point in the history
  • Loading branch information
troykessler authored Dec 16, 2024
1 parent 8136608 commit aab9233
Show file tree
Hide file tree
Showing 77 changed files with 5,124 additions and 1,174 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ An '!' indicates a state machine breaking change.
### Features

- ! (`x/stakers`) [#209](https://github.com/KYVENetwork/chain/pull/209) Shared Staking: Consensus-validator stake is now used for the protocol.
- ! (`x/stakers`) [#210](https://github.com/KYVENetwork/chain/pull/210) Shared Staking: Pool specific commission and stake fraction.

### Bug Fixes

Expand Down
2 changes: 2 additions & 0 deletions app/upgrades/v2_0/upgrade.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ func CreateUpgradeHandler(

// Run KYVE migrations

// TODO: migrate slash params, commission change queues

return migratedVersionMap, err
}
}
32 changes: 32 additions & 0 deletions docs/static/openapi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4698,6 +4698,19 @@ paths:
type: string
format: uint64
description: commission_change_time ...
stake_fraction_change_time:
type: string
format: uint64
description: stake_fraction_change_time ...
vote_slash:
type: string
description: vote_slash ...
upload_slash:
type: string
description: upload_slash ...
timeout_slash:
type: string
description: timeout_slash ...
pool_params:
description: pool_params ...
type: object
Expand Down Expand Up @@ -7545,6 +7558,12 @@ paths:
description: >-
isLeaving indicates if a staker is leaving the given
pool.
commission:
type: string
description: commission ...
stake_fraction:
type: string
description: stake_fraction ...
description: StakerPoolResponse ...
description: stakers ...
description: >-
Expand Down Expand Up @@ -9899,6 +9918,19 @@ paths:
type: string
format: uint64
description: commission_change_time ...
stake_fraction_change_time:
type: string
format: uint64
description: stake_fraction_change_time ...
vote_slash:
type: string
description: vote_slash ...
upload_slash:
type: string
description: upload_slash ...
timeout_slash:
type: string
description: timeout_slash ...
description: >-
QueryParamsResponse is response type for the Query/Params RPC
method.
Expand Down
28 changes: 27 additions & 1 deletion proto/kyve/stakers/v1beta1/events.proto
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,24 @@ message EventUpdateParams {
message EventUpdateCommission {
// staker is the account address of the protocol node.
string staker = 1;
// pool_id ...
uint64 pool_id = 2;
// commission ...
string commission = 2 [
string commission = 3 [
(gogoproto.customtype) = "cosmossdk.io/math.LegacyDec",
(gogoproto.nullable) = false
];
}

// EventUpdateCommission ...
// emitted_by: MsgUpdateStakeFraction, EndBlock
message EventUpdateStakeFraction {
// staker is the account address of the protocol node.
string staker = 1;
// pool_id ...
uint64 pool_id = 2;
// stake_fraction ...
string stake_fraction = 3 [
(gogoproto.customtype) = "cosmossdk.io/math.LegacyDec",
(gogoproto.nullable) = false
];
Expand All @@ -52,6 +68,16 @@ message EventJoinPool {
string valaddress = 3;
// amount is the amount of funds transferred to the valaddress
uint64 amount = 4;
// commission ...
string commission = 5 [
(gogoproto.customtype) = "cosmossdk.io/math.LegacyDec",
(gogoproto.nullable) = false
];
// stake_fraction ...
string stake_fraction = 6 [
(gogoproto.customtype) = "cosmossdk.io/math.LegacyDec",
(gogoproto.nullable) = false
];
}

// EventLeavePool ...
Expand Down
4 changes: 4 additions & 0 deletions proto/kyve/stakers/v1beta1/genesis.proto
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,8 @@ message GenesisState {
repeated LeavePoolEntry leave_pool_entries = 6 [(gogoproto.nullable) = false];
// queue_state_leave ...
QueueState queue_state_leave = 7 [(gogoproto.nullable) = false];
// stake_fraction_change_entries ...
repeated StakeFractionChangeEntry stake_fraction_change_entries = 8 [(gogoproto.nullable) = false];
// queue_state_state_fraction ...
QueueState queue_state_state_fraction = 9 [(gogoproto.nullable) = false];
}
19 changes: 19 additions & 0 deletions proto/kyve/stakers/v1beta1/params.proto
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ syntax = "proto3";

package kyve.stakers.v1beta1;

import "gogoproto/gogo.proto";

option go_package = "github.com/KYVENetwork/chain/x/stakers/types";

// Params defines the stakers module parameters.
Expand All @@ -10,4 +12,21 @@ message Params {
uint64 commission_change_time = 1;
// commission_change_time ...
uint64 leave_pool_time = 2;
// stake_fraction_change_time ...
uint64 stake_fraction_change_time = 3;
// vote_slash ...
string vote_slash = 4 [
(gogoproto.customtype) = "cosmossdk.io/math.LegacyDec",
(gogoproto.nullable) = false
];
// upload_slash ...
string upload_slash = 5 [
(gogoproto.customtype) = "cosmossdk.io/math.LegacyDec",
(gogoproto.nullable) = false
];
// timeout_slash ...
string timeout_slash = 6 [
(gogoproto.customtype) = "cosmossdk.io/math.LegacyDec",
(gogoproto.nullable) = false
];
}
39 changes: 37 additions & 2 deletions proto/kyve/stakers/v1beta1/stakers.proto
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,16 @@ message Valaccount {
uint64 points = 4;
// isLeaving indicates if a staker is leaving the given pool.
bool is_leaving = 5;
// commission ...
string commission = 6 [
(gogoproto.customtype) = "cosmossdk.io/math.LegacyDec",
(gogoproto.nullable) = false
];
// stake_fraction ...
string stake_fraction = 7 [
(gogoproto.customtype) = "cosmossdk.io/math.LegacyDec",
(gogoproto.nullable) = false
];
}

// CommissionChangeEntry stores the information for an
Expand All @@ -66,15 +76,40 @@ message CommissionChangeEntry {
uint64 index = 1;
// staker is the address of the affected staker
string staker = 2;
// pool_id ...
uint64 pool_id = 3;
// commission is the new commission which will
// be applied after the waiting time is over.
string commission = 3 [
string commission = 4 [
(gogoproto.customtype) = "cosmossdk.io/math.LegacyDec",
(gogoproto.nullable) = false
];
// creation_date is the UNIX-timestamp in seconds
// when the entry was created.
int64 creation_date = 4;
int64 creation_date = 5;
}

// StakeFractionChangeEntry stores the information for an
// upcoming stake fraction change. A stake fraction change is
// only instant if it gets increased, if it gets decreased
// the staker needs to wait for the stake fraction change time
message StakeFractionChangeEntry {
// index is needed for the queue-algorithm which
// processes the commission changes
uint64 index = 1;
// staker is the address of the affected staker
string staker = 2;
// pool_id ...
uint64 pool_id = 3;
// stake_fraction is the new stake fraction which will
// be applied after the waiting time is over.
string stake_fraction = 4 [
(gogoproto.customtype) = "cosmossdk.io/math.LegacyDec",
(gogoproto.nullable) = false
];
// creation_date is the UNIX-timestamp in seconds
// when the entry was created.
int64 creation_date = 5;
}

// LeavePoolEntry stores the information for an upcoming
Expand Down
45 changes: 37 additions & 8 deletions proto/kyve/stakers/v1beta1/tx.proto
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,30 @@ option go_package = "github.com/KYVENetwork/chain/x/stakers/types";
// Msg defines the Msg service.
service Msg {
option (cosmos.msg.v1.service) = true;
// UpdateCommission ...
rpc UpdateCommission(MsgUpdateCommission) returns (MsgUpdateCommissionResponse);
// JoinPool ...
rpc JoinPool(MsgJoinPool) returns (MsgJoinPoolResponse);
// LeavePool ...
rpc LeavePool(MsgLeavePool) returns (MsgLeavePoolResponse);

// UpdateCommission ...
rpc UpdateCommission(MsgUpdateCommission) returns (MsgUpdateCommissionResponse);
// UpdateStakeFraction ...
rpc UpdateStakeFraction(MsgUpdateStakeFraction) returns (MsgUpdateStakeFractionResponse);

// UpdateParams defines a governance operation for updating the x/stakers module
// parameters. The authority is hard-coded to the x/gov module account.
rpc UpdateParams(MsgUpdateParams) returns (MsgUpdateParamsResponse);
}

// MsgUpdateCommission ...
// MsgUpdateCommission ... // TODO: create v1 types and rename new to MsgUpdatePoolCommission
message MsgUpdateCommission {
option (cosmos.msg.v1.signer) = "creator";
// creator ...
string creator = 1;
// pool_id ...
uint64 pool_id = 2;
// commission ...
string commission = 2 [
string commission = 3 [
(gogoproto.customtype) = "cosmossdk.io/math.LegacyDec",
(gogoproto.nullable) = false
];
Expand All @@ -38,7 +43,24 @@ message MsgUpdateCommission {
// MsgUpdateCommissionResponse ...
message MsgUpdateCommissionResponse {}

// MsgJoinPool ...
// MsgUpdateStakeFraction ...
message MsgUpdateStakeFraction {
option (cosmos.msg.v1.signer) = "creator";
// creator ...
string creator = 1;
// pool_id ...
uint64 pool_id = 2;
// commission ...
string stake_fraction = 3 [
(gogoproto.customtype) = "cosmossdk.io/math.LegacyDec",
(gogoproto.nullable) = false
];
}

// MsgUpdateStakeFractionResponse ...
message MsgUpdateStakeFractionResponse {}

// MsgJoinPool ... // TODO: create v1 types
message MsgJoinPool {
option (cosmos.msg.v1.signer) = "creator";
// creator ...
Expand All @@ -49,9 +71,16 @@ message MsgJoinPool {
string valaddress = 3;
// amount ...
uint64 amount = 4;

// TODO add stake fraction (in next PR)
// TODO add commission (in next PR)
// commission ...
string commission = 5 [
(gogoproto.customtype) = "cosmossdk.io/math.LegacyDec",
(gogoproto.nullable) = false
];
// stake_fraction ...
string stake_fraction = 6 [
(gogoproto.customtype) = "cosmossdk.io/math.LegacyDec",
(gogoproto.nullable) = false
];
}

// MsgJoinPoolResponse ...
Expand Down
21 changes: 11 additions & 10 deletions testutil/integration/checks.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ func (suite *KeeperTestSuite) VerifyPoolTotalStake() {
actualBalance := suite.App().StakersKeeper.GetDelegationOfPool(suite.Ctx(), pool.Id)

for _, stakerAddress := range suite.App().StakersKeeper.GetAllStakerAddressesOfPool(suite.Ctx(), pool.Id) {
expectedBalance += suite.App().StakersKeeper.GetDelegationAmount(suite.Ctx(), stakerAddress)
expectedBalance += suite.App().StakersKeeper.GetValidatorPoolStake(suite.Ctx(), stakerAddress, pool.Id)
}

Expect(actualBalance).To(Equal(expectedBalance))
Expand Down Expand Up @@ -461,20 +461,21 @@ func (suite *KeeperTestSuite) verifyFullStaker(fullStaker querytypes.FullStaker,
//Expect(fullStaker.Metadata.Commission).To(Equal(staker.Commission))
//Expect(fullStaker.Metadata.Moniker).To(Equal(staker.Description.Moniker))

pendingCommissionChange, found := suite.App().StakersKeeper.GetCommissionChangeEntryByIndex2(suite.Ctx(), stakerAddress)
if found {
Expect(fullStaker.Metadata.PendingCommissionChange.Commission).To(Equal(pendingCommissionChange.Commission))
Expect(fullStaker.Metadata.PendingCommissionChange.CreationDate).To(Equal(pendingCommissionChange.CreationDate))
} else {
Expect(fullStaker.Metadata.PendingCommissionChange).To(BeNil())
}
// TODO rework after commission was implemented
//pendingCommissionChange, found := suite.App().StakersKeeper.GetCommissionChangeEntryByIndex2(suite.Ctx(), stakerAddress)
//if found {
// Expect(fullStaker.Metadata.PendingCommissionChange.Commission).To(Equal(pendingCommissionChange.Commission))
// Expect(fullStaker.Metadata.PendingCommissionChange.CreationDate).To(Equal(pendingCommissionChange.CreationDate))
//} else {
// Expect(fullStaker.Metadata.PendingCommissionChange).To(BeNil())
//}

poolIds := make(map[uint64]bool)

for _, poolMembership := range fullStaker.Pools {
poolIds[poolMembership.Pool.Id] = true
valaccount, found := suite.App().StakersKeeper.GetValaccount(suite.Ctx(), poolMembership.Pool.Id, stakerAddress)
Expect(found).To(BeTrue())
valaccount, active := suite.App().StakersKeeper.GetValaccount(suite.Ctx(), poolMembership.Pool.Id, stakerAddress)
Expect(active).To(BeTrue())

Expect(poolMembership.Valaddress).To(Equal(valaccount.Valaddress))
Expect(poolMembership.IsLeaving).To(Equal(valaccount.IsLeaving))
Expand Down
34 changes: 34 additions & 0 deletions testutil/integration/integration.go
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,40 @@ func (suite *KeeperTestSuite) CreateValidatorWithoutCommit(address, moniker stri
suite.Commit()
}

func (suite *KeeperTestSuite) SelfDelegateValidator(address string, amount uint64) {
valAddress := util.MustValaddressFromOperatorAddress(address)

msg := stakingtypes.NewMsgDelegate(
address,
valAddress,
sdk.NewInt64Coin(globalTypes.Denom, int64(amount)),
)

_, err := suite.RunTx(msg)
if err != nil {
panic(err)
}

suite.Commit()
}

func (suite *KeeperTestSuite) SelfUndelegateValidator(address string, amount uint64) {
valAddress := util.MustValaddressFromOperatorAddress(address)

msg := stakingtypes.NewMsgUndelegate(
address,
valAddress,
sdk.NewInt64Coin(globalTypes.Denom, int64(amount)),
)

_, err := suite.RunTx(msg)
if err != nil {
panic(err)
}

suite.Commit()
}

func (suite *KeeperTestSuite) CreateValidator(address, moniker string, kyveStake int64) {
suite.CreateValidatorWithoutCommit(address, moniker, kyveStake)
suite.Commit()
Expand Down
Loading

0 comments on commit aab9233

Please sign in to comment.