Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DON'T MERGE] feat(x/gov): add governors #16

Draft
wants to merge 47 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
b301574
tally prototype with governors
giunatale Sep 13, 2024
8cb99c2
add protos
giunatale Sep 13, 2024
41b042f
governor object started (copy from Validator)
giunatale Sep 13, 2024
d4a8c03
wip
giunatale Sep 13, 2024
96abd4c
wip
giunatale Sep 14, 2024
f9ad9d8
...
giunatale Sep 14, 2024
700703d
...
giunatale Sep 14, 2024
f6c3392
missing governor election
giunatale Sep 14, 2024
6951d84
not right, cannot iterate on all governors
giunatale Sep 14, 2024
1a8495c
remove percentage and try sorting governors by VP
giunatale Sep 14, 2024
a769118
add msgs
giunatale Sep 14, 2024
ca19aaf
update test mock keepers
giunatale Sep 14, 2024
be1db00
...
giunatale Sep 14, 2024
e1a2bbb
compiles
giunatale Sep 15, 2024
851c005
add query and cli
giunatale Sep 15, 2024
372bca2
allow governor status updates only once a month
giunatale Sep 15, 2024
4ea0dad
genesis
giunatale Sep 15, 2024
fedba97
fix e2e
giunatale Sep 15, 2024
68645f2
add governors vp invariant
giunatale Sep 15, 2024
201b112
iterate over correct values
giunatale Sep 16, 2024
e5c1284
format pass
giunatale Sep 18, 2024
6f37870
fix missing return
giunatale Sep 18, 2024
c0cdec9
cleanup protos
giunatale Sep 19, 2024
80f44c7
Merge branch 'main' into governors
giunatale Sep 24, 2024
afa8d07
fix merge mistake
giunatale Sep 24, 2024
58d6a83
fix merge mistakes
giunatale Sep 24, 2024
44d71e6
approx VP computation for quorum with governors
giunatale Sep 24, 2024
5767cca
fix error in keeper.GetGovernor
giunatale Sep 24, 2024
25d017a
protogen
giunatale Sep 24, 2024
671755c
add min bonding requirements for governors
giunatale Sep 24, 2024
86031e6
governance delegations invariant
giunatale Sep 24, 2024
3a9f71f
fmt pass
giunatale Sep 24, 2024
b8eac36
use math
giunatale Sep 25, 2024
9bcbd0f
remove iteration over map
giunatale Sep 25, 2024
8daaffb
more efficient
giunatale Sep 25, 2024
26ff811
fix
giunatale Sep 25, 2024
ec48fe5
remove ambiguity
giunatale Sep 25, 2024
180e1c1
...
giunatale Sep 25, 2024
e147827
various fixes
giunatale Sep 25, 2024
e0d3865
Merge remote-tracking branch 'origin/main' into governors
giunatale Sep 25, 2024
48f45be
fix error codes
giunatale Sep 25, 2024
0659b9d
add alternative for tallying governors VP
giunatale Sep 25, 2024
8b79c43
tally results updated only once only per voter
giunatale Sep 25, 2024
1f8e5a9
...
giunatale Sep 25, 2024
374c315
Merge remote-tracking branch 'origin/main' into governors
giunatale Sep 27, 2024
90f540c
Merge branch 'main' into governors
giunatale Oct 2, 2024
c5e5ce4
fmt
giunatale Oct 2, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 10 additions & 9 deletions app/keepers/keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -207,15 +207,6 @@ func NewAppKeeper(
authtypes.NewModuleAddress(govtypes.ModuleName).String(),
)

// register the staking hooks
// NOTE: stakingKeeper above is passed by reference, so that it will contain these hooks
appKeepers.StakingKeeper.SetHooks(
stakingtypes.NewMultiStakingHooks(
appKeepers.DistrKeeper.Hooks(),
appKeepers.SlashingKeeper.Hooks(),
),
)

// UpgradeKeeper must be created before IBCKeeper
appKeepers.UpgradeKeeper = upgradekeeper.NewKeeper(
skipUpgradeHeights,
Expand Down Expand Up @@ -266,6 +257,16 @@ func NewAppKeeper(
// If evidence needs to be handled for the app, set routes in router here and seal
appKeepers.EvidenceKeeper = *evidenceKeeper

// register the staking hooks
// NOTE: stakingKeeper above is passed by reference, so that it will contain these hooks
appKeepers.StakingKeeper.SetHooks(
stakingtypes.NewMultiStakingHooks(
appKeepers.DistrKeeper.Hooks(),
appKeepers.SlashingKeeper.Hooks(),
appKeepers.GovKeeper.StakingHooks(),
),
)

return appKeepers
}

Expand Down
6 changes: 3 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ require (
cosmossdk.io/math v1.3.0
cosmossdk.io/simapp v0.0.0-20230602123434-616841b9704d
cosmossdk.io/tools/rosetta v0.2.1
github.com/chzyer/readline v1.5.1
github.com/cometbft/cometbft v0.37.4
github.com/cometbft/cometbft-db v0.10.0
github.com/cosmos/cosmos-proto v1.0.0-beta.4
Expand All @@ -19,6 +20,7 @@ require (
github.com/golang/mock v1.6.0
github.com/google/gofuzz v1.2.0
github.com/gorilla/mux v1.8.1
github.com/manifoldco/promptui v0.9.0
github.com/ory/dockertest/v3 v3.10.0
github.com/rakyll/statik v0.1.7
github.com/spf13/cast v1.6.0
Expand All @@ -30,6 +32,7 @@ require (
golang.org/x/sync v0.4.0
google.golang.org/genproto/googleapis/api v0.0.0-20231212172506-995d672761c0
google.golang.org/protobuf v1.32.0
gopkg.in/yaml.v2 v2.4.0
gotest.tools/v3 v3.5.1
sigs.k8s.io/yaml v1.4.0
)
Expand Down Expand Up @@ -66,7 +69,6 @@ require (
github.com/cenkalti/backoff/v4 v4.1.3 // indirect
github.com/cespare/xxhash v1.1.0 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/chzyer/readline v1.5.1 // indirect
github.com/cockroachdb/apd/v2 v2.0.2 // indirect
github.com/cockroachdb/errors v1.10.0 // indirect
github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect
Expand Down Expand Up @@ -145,7 +147,6 @@ require (
github.com/libp2p/go-buffer-pool v0.1.0 // indirect
github.com/linxGnu/grocksdb v1.8.11 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/manifoldco/promptui v0.9.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
Expand Down Expand Up @@ -203,7 +204,6 @@ require (
google.golang.org/appengine v1.6.8 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240108191215-35c7eff3a6b1 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
nhooyr.io/websocket v1.8.6 // indirect
pgregory.net/rapid v1.1.0 // indirect
Expand Down
5 changes: 5 additions & 0 deletions proto/atomone/gov/v1/genesis.proto
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,9 @@ message GenesisState {
//
// Since: cosmos-sdk 0.47
Params params = 8;

// governors defines all the governors present at genesis.
repeated Governor governors = 9;
// governance_delegations defines all the governance delegations present at genesis.
repeated GovernanceDelegation governance_delegations = 10;
}
86 changes: 86 additions & 0 deletions proto/atomone/gov/v1/gov.proto
Original file line number Diff line number Diff line change
Expand Up @@ -217,4 +217,90 @@ message Params {

// burn deposits if quorum with vote type no_veto is met
bool burn_vote_veto = 15;

// defines the maximum number of governors that can be active at any given time.
uint64 max_governors = 20;
// defines the duration of time that need to elapse between governor status changes.
google.protobuf.Duration governor_status_change_period = 21 [(gogoproto.stdduration) = true];
}


// Governor defines a governor, together with the total amount of delegated
// validator's bond shares for a set amount of validators. When a delegator
// delegates a percentage of its x/gov power to a governor, the resulting
// shares from each delegators delegations in x/staking are added to the
// governor's total shares.
message Governor {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;

// governor_address defines the address of the governor; bech encoded in JSON.
string governor_address = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
// status is the status of the governor (active/inactive).
GovernorStatus status = 2;
// description defines the description terms for the governor.
GovernorDescription description = 3 [(gogoproto.nullable) = false, (amino.dont_omitempty) = true];
// voting_power defines the (estimated) voting power of the governor.
string voting_power = 4 [
(cosmos_proto.scalar) = "cosmos.Dec",
(gogoproto.customtype) = "cosmossdk.io/math.LegacyDec",
(gogoproto.nullable) = false
];

// last_status_change_time is the time when the governor's status was last changed.
google.protobuf.Timestamp last_status_change_time = 5 [(gogoproto.stdtime) = true];
}

// GovernorStatus is the status of a governor.
enum GovernorStatus {
option (gogoproto.goproto_enum_prefix) = false;

// UNSPECIFIED defines an invalid governor status.
GOVERNOR_STATUS_UNSPECIFIED = 0 [(gogoproto.enumvalue_customname) = "Unspecified"];
// ACTIVE defines a governor that is active.
GOVERNOR_STATUS_ACTIVE = 1 [(gogoproto.enumvalue_customname) = "Active"];
// INACTIVE defines a governor that is inactive.
GOVERNOR_STATUS_INACTIVE = 2 [(gogoproto.enumvalue_customname) = "Inactive"];
}

// Description defines a governor description.
message GovernorDescription {
option (gogoproto.equal) = true;

// moniker defines a human-readable name for the governor.
string moniker = 1;
// identity defines an optional identity signature (ex. UPort or Keybase).
string identity = 2;
// website defines an optional website link.
string website = 3;
// security_contact defines an optional email for security contact.
string security_contact = 4;
// details define other optional details.
string details = 5;
}

// GovernorValShares holds the number of shares from the specific validator
// that a governor can use to vote on proposals.
message GovernorValShares {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;

string governor_address = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
string validator_address = 2 [(cosmos_proto.scalar) = "cosmos.ValidatorAddressString"];
// shares define the delegation shares available from this validator.
string shares = 3 [
(cosmos_proto.scalar) = "cosmos.Dec",
(gogoproto.customtype) = "cosmossdk.io/math.LegacyDec",
(gogoproto.nullable) = false
];
}

// GovernanceDelegation defines a delegation of governance voting power from a
// delegator to a governor.
message GovernanceDelegation {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;

string delegator_address = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
string governor_address = 2 [(cosmos_proto.scalar) = "cosmos.AddressString"];
}
100 changes: 100 additions & 0 deletions proto/atomone/gov/v1/query.proto
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,31 @@ service Query {
rpc TallyResult(QueryTallyResultRequest) returns (QueryTallyResultResponse) {
option (google.api.http).get = "/atomone/gov/v1/proposals/{proposal_id}/tally";
}

// Governor queries governor information based on governor address.
rpc Governor(QueryGovernorRequest) returns (QueryGovernorResponse) {
option (google.api.http).get = "/atomone/gov/v1/governor/{governor_address}";
}

// Governors queries all governors.
rpc Governors(QueryGovernorsRequest) returns (QueryGovernorsResponse) {
option (google.api.http).get = "/atomone/gov/v1/governors";
}

// GovernanceDelegations queries all delegations of a governor.
rpc GovernanceDelegations(QueryGovernanceDelegationsRequest) returns (QueryGovernanceDelegationsResponse) {
option (google.api.http).get = "/atomone/gov/v1/governors/{governor_address}/delegations";
}

// GovernanceDelegation queries a delegation
rpc GovernanceDelegation(QueryGovernanceDelegationRequest) returns (QueryGovernanceDelegationResponse) {
option (google.api.http).get = "/atomone/gov/v1/delegations/{delegator_address}";
}

// GovernorValShares queries all governor validator shares resulting from all governance delegations.
rpc GovernorValShares(QueryGovernorValSharesRequest) returns (QueryGovernorValSharesResponse) {
option (google.api.http).get = "/atomone/gov/v1/valshares/{governor_address}";
}
}

// QueryProposalRequest is the request type for the Query/Proposal RPC method.
Expand Down Expand Up @@ -191,3 +216,78 @@ message QueryTallyResultResponse {
// tally defines the requested tally.
TallyResult tally = 1;
}

// QueryGovernorRequest is the request type for the Query/Governor RPC method.
message QueryGovernorRequest {
// gvernor_address defines the address of the governor.
string governor_address = 1 [(cosmos_proto.scalar) = "atomone.GovernorAddressString"];
}

// QueryGovernorResponse is the response type for the Query/Governor RPC method.
message QueryGovernorResponse {
// governor defines the requested governor.
Governor governor = 1;
}

// QueryGovernorsRequest is the request type for the Query/Governors RPC method.
message QueryGovernorsRequest {
// pagination defines an optional pagination for the request.
cosmos.base.query.v1beta1.PageRequest pagination = 1;
}

// QueryGovernorsResponse is the response type for the Query/Governors RPC method.
message QueryGovernorsResponse {
// governors defines the requested governors.
repeated Governor governors = 1;

// pagination defines the pagination in the response.
cosmos.base.query.v1beta1.PageResponse pagination = 2;
}

// QueryGovernanceDelegationsRequest is the request type for the Query/GovernanceDelegations RPC method.
message QueryGovernanceDelegationsRequest {
// governor_address defines the address of the governor.
string governor_address = 1 [(cosmos_proto.scalar) = "atomone.GovernorAddressString"];

// pagination defines an optional pagination for the request.
cosmos.base.query.v1beta1.PageRequest pagination = 2;
}

// QueryGovernanceDelegationsResponse is the response type for the Query/GovernanceDelegations RPC method.
message QueryGovernanceDelegationsResponse {
// delegations defines the requested delegations.
repeated GovernanceDelegation delegations = 1;

// pagination defines the pagination in the response.
cosmos.base.query.v1beta1.PageResponse pagination = 2;
}

// QueryGovernanceDelegationRequest is the request type for the Query/GovernanceDelegation RPC method.
message QueryGovernanceDelegationRequest {
// delegator_address defines the address of the delegator.
string delegator_address = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
}

// QueryGovernanceDelegationResponse is the response type for the Query/GovernanceDelegation RPC method.
message QueryGovernanceDelegationResponse {
// governor_address defines the address of the governor.
string governor_address = 1;
}

// QueryGovernorValSharesRequest is the request type for the Query/GovernorValShares RPC method.
message QueryGovernorValSharesRequest {
// governor_address defines the address of the governor.
string governor_address = 1 [(cosmos_proto.scalar) = "atomone.GovernorAddressString"];

// pagination defines the pagination in the request.
cosmos.base.query.v1beta1.PageRequest pagination = 2;
}

// QueryGovernorValSharesResponse is the response type for the Query/GovernorValShares RPC method.
message QueryGovernorValSharesResponse {
// val_shares defines the requested validator shares.
repeated GovernorValShares val_shares = 1;

// pagination defines the pagination in the response.
cosmos.base.query.v1beta1.PageResponse pagination = 2;
}
92 changes: 92 additions & 0 deletions proto/atomone/gov/v1/tx.proto
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,23 @@ service Msg {
//
// Since: cosmos-sdk 0.47
rpc UpdateParams(MsgUpdateParams) returns (MsgUpdateParamsResponse);

// CreateGovernor defines a method to create a new governor.
rpc CreateGovernor(MsgCreateGovernor) returns (MsgCreateGovernorResponse);

// EditGovernor defines a method to edit an existing governor.
// It also sets its status.
rpc EditGovernor(MsgEditGovernor) returns (MsgEditGovernorResponse);

// UpdateGovernorStatus defines a method to update the status of a governor.
rpc UpdateGovernorStatus(MsgUpdateGovernorStatus) returns (MsgUpdateGovernorStatusResponse);

// DelegateGovernor defines a method to delegate a non-zero percentange of
// governance voting power from a delegator to a governor.
rpc DelegateGovernor(MsgDelegateGovernor) returns (MsgDelegateGovernorResponse);

// UndelegateGovernor defines a method to undelegate governance voting power
rpc UndelegateGovernor(MsgUndelegateGovernor) returns (MsgUndelegateGovernorResponse);
}

// MsgSubmitProposal defines an sdk.Msg type that supports submitting arbitrary
Expand Down Expand Up @@ -170,3 +187,78 @@ message MsgUpdateParams {
//
// Since: cosmos-sdk 0.47
message MsgUpdateParamsResponse {}

// MsgCreateGovernor defines a SDK message for creating a new governor.
message MsgCreateGovernor {
option (cosmos.msg.v1.signer) = "address";
option (amino.name) = "atomone/MsgCreateGovernor";

option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;

GovernorDescription description = 1 [(gogoproto.nullable) = false, (amino.dont_omitempty) = true];
string address = 2 [(cosmos_proto.scalar) = "cosmos.AddressString"];
}

// MsgCreateGovernorrResponse defines the Msg/CreateGovernor response type.
message MsgCreateGovernorResponse {}

// MsgEditGovernor defines a SDK message for editing an existing governor.
message MsgEditGovernor {
option (cosmos.msg.v1.signer) = "address";
option (amino.name) = "cosmos-sdk/MsgEditGovernor";

option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;

GovernorDescription description = 1 [(gogoproto.nullable) = false, (amino.dont_omitempty) = true];
string address = 2 [(cosmos_proto.scalar) = "cosmos.AddressString"];
}

// MsgEditGovernorResponse defines the Msg/EditGovernor response type.
message MsgEditGovernorResponse {}

// MsgUpdateGovernorStatus defines a SDK message for updating the status of a governor.
message MsgUpdateGovernorStatus {
option (cosmos.msg.v1.signer) = "address";
option (amino.name) = "cosmos-sdk/MsgUpdateGovernorStatus";

option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;

string address = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
GovernorStatus status = 2;
}

// MsgUpdateGovernorStatusResponse defines the Msg/UpdateGovernorStatus response type.
message MsgUpdateGovernorStatusResponse {}

// MsgDelegateGovernor defines a SDK message for performing a delegation of governance voting power
// from a delegator to a governor.
message MsgDelegateGovernor {
option (cosmos.msg.v1.signer) = "delegator_address";
option (amino.name) = "atomone/MsgDelegateGovernor";

option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;

string delegator_address = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
string governor_address = 2 [(cosmos_proto.scalar) = "atomone.GovernorAddressString"];
}

// MsgDelegateGovernorResponse defines the Msg/Delegate response type.
message MsgDelegateGovernorResponse {}

// MsgUndelegateGovernor defines a SDK message for undelegating governance voting power
message MsgUndelegateGovernor {
option (cosmos.msg.v1.signer) = "delegator_address";
option (amino.name) = "cosmos-sdk/MsgUndelegateGovernor";

option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;

string delegator_address = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
}

// MsgUndelegateGovernorResponse defines the Msg/UndelegateGovernor response type.
message MsgUndelegateGovernorResponse {}
Loading
Loading