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

feat(x/gov): add governors #73

Open
wants to merge 63 commits into
base: main
Choose a base branch
from

Conversation

giunatale
Copy link
Collaborator

@giunatale giunatale commented Jan 14, 2025

iterating over the work started in #16, this PR adds governors to the x/gov module.

More details can be also read in #16

Only sketching out how the tally would work for now.
Lots of stuff is left undefined but the strategy is the one outlined in https://gist.github.com/giunatale/95e9b43f6e265ba32b29e2769f7b8a37?permalink_comment_id=5067400#gistcomment-5067400 but with the restriction of being able to delegate a percentage of its bonded tokens to at most one governor (https://gist.github.com/giunatale/95e9b43f6e265ba32b29e2769f7b8a37?permalink_comment_id=5187246#gistcomment-5187246)

It assumes that every time someone redelegates, undelegates or adds to its delegations a hook is called to check if there is a governor delegated to in x/gov, and the governor's total shares updated accordingly.
The governor's total shares are a collection of share amounts for different validators.
can only delegate all or nothing to governors now
@giunatale
Copy link
Collaborator Author

since this work was left untouched for a while, we need to give it a final pass to identify potentially missing tests and check test coverage, and add documentation. Ideally we would also want to do some more in depth profiling/benchmarking to assess the performance impact of this addition.

Comment on lines +248 to +254
for _, govInfo := range allGovernors {
governor, _ := k.GetGovernor(ctx, govInfo.Address)

if k.ValidateGovernorMinSelfDelegation(ctx, governor) && len(govInfo.Vote) > 0 {
governorsInfos = append(governorsInfos, govInfo)
}
}

Check warning

Code scanning / CodeQL

Iteration over map Warning

Iteration over map may be a possible source of non-determinism
Comment on lines +261 to +266
for valAddrStr, shares := range governor.ValShares {
if val, ok := currValidators[valAddrStr]; ok {
sharesAfterDeductions := shares.Sub(governor.ValSharesDeductions[valAddrStr])
votingPower = votingPower.Add(sharesAfterDeductions.MulInt(val.GetBondedTokens()).Quo(val.GetDelegatorShares()))
}
}

Check warning

Code scanning / CodeQL

Iteration over map Warning

Iteration over map may be a possible source of non-determinism

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

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would rather see singular delegation here, as it will always return a single.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is for consistency, the plural is used in other places too (e.g. proposals)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Understandable, then the first one /atomone/gov/v1/governor/{governor_address} should be /atomone/gov/v1/governors/{governor_address} ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but also e.g. validator info for a single validator in x/staking is "validators/{validator-address}"

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Understandable, then the first one /atomone/gov/v1/governor/{governor_address} should be /atomone/gov/v1/governors/{governor_address} ?

yes

tbruyelle and others added 6 commits January 16, 2025 09:57
* add governors adr

* Update docs/architecture/adr-004-governors.md

Co-authored-by: Thomas Bruyelle <thomas.bruyelle@gmail.com>

---------

Co-authored-by: Thomas Bruyelle <thomas.bruyelle@gmail.com>
* add governors documentation

* add txs in CLI section
The gov module InitGenesis must happen after staking because governors
requires to access the validator delegations.
* perf(x/gov): remove useless bech32 conversion

Accessing `delegation.ValidatorAddress` is similar to calling
`delegation.GetValidatorAddress().String()` but w/o useless conversions.

* perf(x/gov): remove useless address conversion

* perf(x/gov): remove useless bech32 conversion

* perf(x/gov): remove unused active field from GovernorGovInfo

* perf(x/gov): assume vote weight is 1 most of the time
tbruyelle added a commit to tbruyelle/atomone that referenced this pull request Feb 3, 2025
Spotted by `make vulncheck`

Last seen in
https://github.com/atomone-hub/atomone/actions/runs/12228478419/job/34106805715#step:4:14

```
Vulnerability atomone-hub#1: GO-2024-3279
    ASA-2024-010: cosmossdk.io/math: Mismatched bit-length validation in sdk.Int
    and sdk.Dec can lead to panic
  More info: https://pkg.go.dev/vuln/GO-2024-3279
  Module: cosmossdk.io/math
    Found in: cosmossdk.io/math@v1.3.0
    Fixed in: cosmossdk.io/math@v1.4.0
    Example traces found:
Error:       atomone-hub#1: app/export.go:209:63: app.AtomOneApp.prepForZeroHeightGenesis calls keeper.Keeper.ApplyAndReturnValidatorSetUpdates, which calls math.Int.Add
Error:       atomone-hub#2: app/genesis_account.go:31:33: app.SimGenesisAccount.Validate calls types.Coins.IsAnyNil, which eventually calls math.Int.BigInt
Error:       atomone-hub#3: x/gov/types/v1beta1/gov.pb.go:732:20: v1beta1.TallyResult.Equal calls math.Int.Equal
Error:       atomone-hub#4: x/gov/keeper/deposit.go:180:97: keeper.Keeper.AddDeposit calls types.Coins.IsAllGTE, which calls math.Int.GT
Error:       atomone-hub#5: ante/gov_vote_ante.go:46:[14](https://github.com/atomone-hub/atomone/actions/runs/12228478419/job/34106805715#step:4:15): ante.GovVoteDecorator.AnteHandle calls types.ChainAnteDecorators, which eventually calls math.Int.GTE
Error:       atomone-hub#6: app/app.go:254:26: app.AtomOneApp.BeginBlocker calls module.Manager.BeginBlock, which eventually calls math.Int.Int64
Error:       atomone-hub#7: app/app.go:254:26: app.AtomOneApp.BeginBlocker calls module.Manager.BeginBlock, which eventually calls math.Int.IsInt64
Error:       atomone-hub#8: x/gov/keeper/deposit.go:145:28: keeper.Keeper.AddDeposit calls types.NewCoin, which eventually calls math.Int.IsNegative
Error:       atomone-hub#9: x/gov/types/v1/msgs.go:101:30: types.MsgSubmitProposal.ValidateBasic calls types.MsgCancelUnbondingDelegation.ValidateBasic, which calls math.Int.IsPositive
Error:       atomone-hub#10: x/gov/keeper/tally.go:58:23: keeper.Keeper.HasReachedQuorum calls math.Int.IsZero
Error:       atomone-hub#11: x/gov/keeper/deposit.go:[15](https://github.com/atomone-hub/atomone/actions/runs/12228478419/job/34106805715#step:4:16)5:20: keeper.Keeper.AddDeposit calls types.Coin.IsGTE, which calls math.Int.LT
Error:       atomone-hub#12: x/gov/keeper/deposit.go:63:37: keeper.DeleteAndBurnDeposits calls keeper.BaseKeeper.BurnCoins, which eventually calls math.Int.Marshal
Error:       atomone-hub#13: x/gov/types/v1beta1/gov.pb.go:994:38: v1beta1.TallyResult.MarshalToSizedBuffer calls math.Int.MarshalTo
Error:       atomone-hub#14: app/export.go:11:2: app.init calls staking.init, which eventually calls math.Int.Mul
Error:       atomone-hub#15: x/gov/keeper/deposit.go:[16](https://github.com/atomone-hub/atomone/actions/runs/12228478419/job/34106805715#step:4:17)8:54: keeper.Keeper.AddDeposit calls keeper.BaseKeeper.SendCoinsFromAccountToModule, which eventually calls math.Int.Neg
Error:       atomone-hub#16: app/export.go:209:63: app.AtomOneApp.prepForZeroHeightGenesis calls keeper.Keeper.ApplyAndReturnValidatorSetUpdates, which eventually calls math.Int.Quo
Error:       #[17](https://github.com/atomone-hub/atomone/actions/runs/12228478419/job/34106805715#step:4:18): ante/gov_vote_ante.go:46:14: ante.GovVoteDecorator.AnteHandle calls types.ChainAnteDecorators, which eventually calls math.Int.QuoRaw
Error:       #[18](https://github.com/atomone-hub/atomone/actions/runs/12228478419/job/34106805715#step:4:19): x/gov/types/v1beta1/msgs.go:167:29: v1beta1.MsgDeposit.ValidateBasic calls types.Coins.IsAnyNegative, which eventually calls math.Int.Sign
Error:       #[19](https://github.com/atomone-hub/atomone/actions/runs/12228478419/job/34106805715#step:4:20): x/gov/types/v1beta1/gov.pb.go:1322:16: v1beta1.TallyResult.Size calls math.Int.Size
Error:       #[20](https://github.com/atomone-hub/atomone/actions/runs/12228478419/job/34106805715#step:4:21): x/gov/types/v1/tally.go:12:27: types.NewTallyResult calls math.Int.String
Error:       #[21](https://github.com/atomone-hub/atomone/actions/runs/12228478419/job/34106805715#step:4:22): app/export.go:209:63: app.AtomOneApp.prepForZeroHeightGenesis calls keeper.Keeper.ApplyAndReturnValidatorSetUpdates, which calls math.Int.Sub
Error:       #[22](https://github.com/atomone-hub/atomone/actions/runs/12228478419/job/34106805715#step:4:23): x/gov/keeper/deposit.go:145:73: keeper.Keeper.AddDeposit calls math.Int.ToLegacyDec
Error:       atomone-hub#23: x/gov/types/v1beta1/gov.pb.go:2141:29: v1beta1.TallyResult.Unmarshal calls math.Int.Unmarshal
Error:       atomone-hub#24: x/gov/types/v1beta1/msgs.go:263:32: v1beta1.MsgVoteWeighted.ValidateBasic calls math.LegacyDec.Add
Error:       atomone-hub#25: app/sim/sim_state.go:203:34: sim.AppStateRandomizedFn calls module.SimulationManager.GenerateGenesisStates, which eventually calls math.LegacyDec.BigInt
Error:       atomone-hub#26: ante/gov_vote_ante.go:46:14: ante.GovVoteDecorator.AnteHandle calls types.ChainAnteDecorators, which eventually calls math.LegacyDec.Ceil
Error:       atomone-hub#27: x/gov/types/v1beta1/params.go:68:[24](https://github.com/atomone-hub/atomone/actions/runs/12228478419/job/34106805715#step:4:25): v1beta1.TallyParams.Equal calls math.LegacyDec.Equal
Error:       atomone-hub#28: x/gov/client/cli/query.go:624:15: cli.GetCmdQueryProposer calls fmt.Sprintf, which eventually calls math.LegacyDec.Format
Error:       atomone-hub#29: x/gov/types/v1beta1/msgs.go:270:19: v1beta1.MsgVoteWeighted.ValidateBasic calls math.LegacyDec.GT
Error:       atomone-hub#30: x/gov/keeper/tally.go:93:26: keeper.Keeper.HasReachedQuorum calls math.LegacyDec.GTE
Error:       atomone-hub#31: x/gov/types/v1/params.go:129:22: types.Params.ValidateBasic calls math.LegacyDec.IsNegative
Error:       atomone-hub#32: x/gov/types/v1/msgs.go:101:30: types.MsgSubmitProposal.ValidateBasic calls types.MsgUpdateParams.ValidateBasic, which calls math.LegacyDec.IsNil
Error:       atomone-hub#33: x/gov/types/v1/params.go:140:26: types.Params.ValidateBasic calls math.LegacyDec.IsPositive
Error:       atomone-hub#34: x/gov/keeper/deposit.go:138:28: keeper.Keeper.AddDeposit calls math.LegacyDec.IsZero
Error:       atomone-hub#35: x/gov/types/v1beta1/msgs.go:274:19: v1beta1.MsgVoteWeighted.ValidateBasic calls math.LegacyDec.LT
Error:       atomone-hub#36: app/export.go:96:53: app.AtomOneApp.prepForZeroHeightGenesis calls keeper.Keeper.WithdrawDelegationRewards, which eventually calls math.LegacyDec.LTE
Error:       atomone-hub#37: app/app.go:[25](https://github.com/atomone-hub/atomone/actions/runs/12228478419/job/34106805715#step:4:26)4:26: app.AtomOneApp.BeginBlocker calls module.Manager.BeginBlock, which eventually calls math.LegacyDec.Marshal
Error:       atomone-hub#38: x/gov/types/v1beta1/gov.pb.go:1187:41: v1beta1.TallyParams.MarshalToSizedBuffer calls math.LegacyDec.MarshalTo
Error:       atomone-hub#39: x/gov/keeper/deposit.go:145:79: keeper.Keeper.AddDeposit calls math.LegacyDec.Mul
Error:       atomone-hub#40: x/gov/keeper/tally.go:1[26](https://github.com/atomone-hub/atomone/actions/runs/12228478419/job/34106805715#step:4:27):31: keeper.tallyVotes calls keeper.Keeper.IterateDelegations, which eventually calls math.LegacyDec.MulInt
Error:       atomone-hub#41: app/export.go:96:53: app.AtomOneApp.prepForZeroHeightGenesis calls keeper.Keeper.WithdrawDelegationRewards, which eventually calls math.LegacyDec.MulInt64
Error:       atomone-hub#42: app/app.go:254:26: app.AtomOneApp.BeginBlocker calls module.Manager.BeginBlock, which eventually calls math.LegacyDec.MulTruncate
Error:       atomone-hub#43: app/export.go:151:60: app.AtomOneApp.prepForZeroHeightGenesis calls keeper.Hooks.BeforeDelegationCreated, which eventually calls math.LegacyDec.Neg
Error:       atomone-hub#44: x/gov/keeper/tally.go:88:39: keeper.Keeper.HasReachedQuorum calls math.LegacyDec.Quo
Error:       atomone-hub#45: app/app.go:254:26: app.AtomOneApp.BeginBlocker calls module.Manager.BeginBlock, which eventually calls math.LegacyDec.QuoInt
Error:       atomone-hub#46: app/app.go:254:26: app.AtomOneApp.BeginBlocker calls module.Manager.BeginBlock, which eventually calls math.LegacyDec.QuoRoundUp
Error:       atomone-hub#47: app/export.go:96:53: app.AtomOneApp.prepForZeroHeightGenesis calls keeper.Keeper.WithdrawDelegationRewards, which eventually calls math.LegacyDec.QuoTruncate
Error:       atomone-hub#48: x/gov/keeper/deposit.go:246:112: keeper.Keeper.validateInitialDeposit calls math.LegacyDec.RoundInt
Error:       atomone-hub#49: x/gov/simulation/genesis.go:84:52: simulation.GenTallyParamsConstitutionalThreshold calls math.LegacyDec.RoundInt64
Error:       atomone-hub#50: x/gov/types/v1beta1/gov.pb.go:1392:19: v1beta1.TallyParams.Size calls math.LegacyDec.Size
Error:       atomone-hub#51: x/gov/keeper/msg_server.go:[27](https://github.com/atomone-hub/atomone/actions/runs/12228478419/job/34106805715#step:4:28)4:29: keeper.legacyMsgServer.VoteWeighted calls math.LegacyDec.String
Error:       atomone-hub#52: x/gov/keeper/tally.go:41:25: keeper.Keeper.Tally calls math.LegacyDec.Sub
Error:       atomone-hub#53: x/gov/keeper/deposit.go:145:108: keeper.Keeper.AddDeposit calls math.LegacyDec.TruncateInt
Error:       atomone-hub#54: cmd/atomoned/main.go:16:26: atomoned.main calls cmd.Execute, which eventually calls math.LegacyDec.TruncateInt64
Error:       atomone-hub#55: x/gov/types/v1beta1/gov.pb.go:2680:32: v1beta1.TallyParams.Unmarshal calls math.LegacyDec.Unmarshal
Error:       atomone-hub#56: app/export.go:96:53: app.AtomOneApp.prepForZeroHeightGenesis calls keeper.Keeper.WithdrawDelegationRewards, which eventually calls math.LegacyMinDec
Error:       atomone-hub#57: x/gov/simulation/genesis.go:73:37: simulation.GenMinDepositRatio calls math.LegacyMustNewDecFromStr
Error:       atomone-hub#58: x/gov/types/v1beta1/msgs.go:257:34: v1beta1.MsgVoteWeighted.ValidateBasic calls math.LegacyNewDec
Error:       atomone-hub#59: app/sim/sim_state.go:203:34: sim.AppStateRandomizedFn calls module.SimulationManager.GenerateGenesisStates, which eventually calls math.LegacyNewDecFromBigIntWithPrec
Error:       atomone-hub#60: x/gov/keeper/tally.go:88:64: keeper.Keeper.HasReachedQuorum calls math.LegacyNewDecFromInt
Error:       atomone-hub#61: x/gov/keeper/grpc_query.go:406:35: keeper.legacyQueryServer.Params calls math.LegacyNewDecFromStr
Error:       atomone-hub#62: x/gov/simulation/genesis.go:85:27: simulation.GenTallyParamsConstitutionalThreshold calls math.LegacyNewDecWithPrec
Error:       atomone-hub#63: x/gov/types/v1/params.go:132:32: types.Params.ValidateBasic calls math.LegacyOneDec
Error:       atomone-hub#64: app/export.go:96:53: app.AtomOneApp.prepForZeroHeightGenesis calls keeper.Keeper.WithdrawDelegationRewards, which eventually calls math.LegacySmallestDec
Error:       atomone-hub#65: x/gov/keeper/tally.go:41:77: keeper.Keeper.Tally calls math.LegacyZeroDec
Error:       atomone-hub#66: app/app.go:254:26: app.AtomOneApp.BeginBlocker calls module.Manager.BeginBlock, which eventually calls math.MaxInt
Error:       atomone-hub#67: app/app.go:254:26: app.AtomOneApp.BeginBlocker calls module.Manager.BeginBlock, which eventually calls math.MinInt
Error:       atomone-hub#68: app/helpers/test_helpers.go:79:69: helpers.Setup calls math.NewInt
Error:       atomone-hub#69: x/gov/keeper/proposal.go:72:24: keeper.Keeper.SubmitProposal calls baseapp.RegisterService, which eventually calls math.NewIntFromBigInt
Error:       atomone-hub#70: x/gov/migrations/v3/convert.go:73:35: migrations.ConvertToLegacyTallyResult calls math.NewIntFromString
Error:       atomone-hub#71: x/gov/types/v1beta1/codec.go:7:2: v1beta1.init calls types.init, which calls math.NewIntFromUint64
Error:       atomone-hub#72: app/sim/sim_state.go:203:34: sim.AppStateRandomizedFn calls module.SimulationManager.GenerateGenesisStates, which eventually calls math.OneInt
Error:       atomone-hub#73: x/gov/types/v1beta1/tally.go:55:36: v1beta1.EmptyTallyResult calls math.ZeroInt
Error:       atomone-hub#74: app/sim/sim_state.go:205:[31](https://github.com/atomone-hub/atomone/actions/runs/12228478419/job/34106805715#step:4:32): sim.AppStateRandomizedFn calls json.Marshal, which eventually calls math.init
Error:       atomone-hub#75: x/gov/types/v1beta1/genesis.go:6:2: v1beta1.init calls math.init
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants