From a61ca4fdd4922e18ff6587a15bc6dd4866e343e1 Mon Sep 17 00:00:00 2001 From: Callum Waters Date: Thu, 2 Dec 2021 19:13:08 +0100 Subject: [PATCH] docs: update gov spec with proposal changes (#10594) --- x/gov/spec/01_concepts.md | 83 ++++++++++++++++++-------------------- x/gov/spec/02_state.md | 84 +++++++++++++++++++-------------------- x/gov/spec/03_messages.md | 4 +- x/gov/spec/07_client.md | 12 ++++-- 4 files changed, 90 insertions(+), 93 deletions(-) diff --git a/x/gov/spec/01_concepts.md b/x/gov/spec/01_concepts.md index 91baf65ce4..ed895973e1 100644 --- a/x/gov/spec/01_concepts.md +++ b/x/gov/spec/01_concepts.md @@ -13,68 +13,61 @@ The governance process is divided in a few steps that are outlined below: - **Vote:** Once deposit reaches a certain value (`MinDeposit`), proposal is confirmed and vote opens. Bonded Atom holders can then send `TxGovVote` transactions to vote on the proposal. -- If the proposal involves a software upgrade: - - **Signal:** Validators start signaling that they are ready to switch to the - new version. - - **Switch:** Once more than 75% of validators have signaled that they are - ready to switch, their software automatically flips to the new version. +- **Execution** After a period of time, the votes are tallied and depending + on the result, the messages in the proposal will be executed. ## Proposal submission ### Right to submit a proposal -Any Atom holder, whether bonded or unbonded, can submit proposals by sending a -`TxGovProposal` transaction. Once a proposal is submitted, it is identified by -its unique `proposalID`. +Every account can submit proposals by sending a `MsgSubmitProposal` transaction. +Once a proposal is submitted, it is identified by its unique `proposalID`. -### Proposal types +### Proposal Messages -In the initial version of the governance module, there are five types of -proposals: - -- `TextProposal` All the proposals that do not involve a modification of - the source code go under this type. For example, an opinion poll would use a - proposal of type `TextProposal`. -- `SoftwareUpgradeProposal`. If accepted, validators are expected to update - their software in accordance with the proposal. They must do so by following - a 2-steps process described in the [Software Upgrade](#software-upgrade) - section below. Software upgrade roadmap may be discussed and agreed on via - `TextProposals`, but actual software upgrades must be performed via - `SoftwareUpgradeProposals`. -- `CommunityPoolSpendProposal` details a proposal for use of community funds, - together with how many coins are proposed to be spent, and to which recipient account. -- `ParameterChangeProposal` defines a proposal to change one or - more parameters. If accepted, the requested parameter change is updated - automatically by the proposal handler upon conclusion of the voting period. -- `CancelSoftwareUpgradeProposal` is a gov Content type for cancelling a software upgrade. - -Other modules may expand upon the governance module by implementing their own -proposal types and handlers. These types are registered and processed through the -governance module (eg. `ParamChangeProposal`), which then execute the respective -module's proposal handler when a proposal passes. This custom handler may perform -arbitrary state changes. +A proposal includes an array of `sdk.Msg`s which are executed automatically if the +proposal passes. The messages are executed by the governance `ModuleAccount` itself. Modules +such as `x/upgrade`, that want to allow certain messages to be executed by governance +only should add a whitelist within the respective msg server, granting the governance +module the right to execute the message once a quorum has been reached. The governance +module uses the `MsgServiceRouter` to check that these messages are correctly constructed +and have a respective path to execute on but do not perform a full validity check. ## Deposit -To prevent spam, proposals must be submitted with a deposit in the coins defined in the `MinDeposit` param. +To prevent spam, proposals must be submitted with a deposit in the coins defined by +the `MinDeposit` param. -When a proposal is submitted, it has to be accompanied with a deposit that must be strictly positive, but can be inferior to `MinDeposit`. The submitter doesn't need to pay for the entire deposit on their own. -The newly created proposal is stored in an _inactive proposal queue_ and stays there until its deposit passes the `MinDeposit`. Other token holders can increase the proposal's deposit by sending a `Deposit` transaction. -If a proposal doesn't pass the `MinDeposit` before the deposit end time (the time when deposits are no longer accepted), the proposal will be destroyed: the proposal will be removed from state and the deposit will be burned (see x/gov `EndBlocker`). -When a proposal deposit passes the `MinDeposit` threshold (even during the proposal submission) before the deposit end time, the proposal will be moved into the _active proposal queue_ and the voting period will begin. +When a proposal is submitted, it has to be accompanied with a deposit that must be +strictly positive, but can be inferior to `MinDeposit`. The submitter doesn't need +to pay for the entire deposit on their own. The newly created proposal is stored in +an _inactive proposal queue_ and stays there until its deposit passes the `MinDeposit`. +Other token holders can increase the proposal's deposit by sending a `Deposit` +transaction. If a proposal doesn't pass the `MinDeposit` before the deposit end time +(the time when deposits are no longer accepted), the proposal will be destroyed: the +proposal will be removed from state and the deposit will be burned (see x/gov `EndBlocker`). +When a proposal deposit passes the `MinDeposit` threshold (even during the proposal +submission) before the deposit end time, the proposal will be moved into the +_active proposal queue_ and the voting period will begin. -The deposit is kept in escrow and held by the governance `ModuleAccount` until the proposal is finalized (passed or rejected). +The deposit is kept in escrow and held by the governance `ModuleAccount` until the +proposal is finalized (passed or rejected). ### Deposit refund and burn -When a proposal is finalized, the coins from the deposit are either refunded or burned, according to the final tally of the proposal: +When a proposal is finalized, the coins from the deposit are either refunded or burned +according to the final tally of the proposal: -- If the proposal is approved or rejected but _not_ vetoed, each deposit will be automatically refunded to its respective depositor (transferred from the governance `ModuleAccount`). -- When the proposal is vetoed with a supermajority, deposits will be burned from the governance `ModuleAccount` and the proposal information along with its deposit information will be removed from state. -- All refunded or burned deposits are removed from the state. Events are issued when burning or refunding a deposit. -- NOTE: The proposals which completed the voting period, cannot return the deposits when queried. +- If the proposal is approved or rejected but _not_ vetoed, each deposit will be + automatically refunded to its respective depositor (transferred from the governance + `ModuleAccount`). +- When the proposal is vetoed with greater than 1/3, deposits will be burned from the + governance `ModuleAccount` and the proposal information along with its deposit + information will be removed from state. +- All refunded or burned deposits are removed from the state. Events are issued when + burning or refunding a deposit. -## Vote +## Voting ### Participants diff --git a/x/gov/spec/02_state.md b/x/gov/spec/02_state.md index 269ff69272..ed9fcdee7b 100644 --- a/x/gov/spec/02_state.md +++ b/x/gov/spec/02_state.md @@ -4,6 +4,48 @@ order: 2 # State +## Proposals + +`Proposal` objects are used to tally votes and generally track the proposal's state. +They contain an array of arbitrary `sdk.Msg`'s which the governance module will attempt +to resolve and then execute if the proposal passes. `Proposal`'s are identified by a +unique id and contains a series of timestamps: `submit_time`, `deposit_end_time`, +`voting_start_time`, `voting_end_time` which track the lifecycle of a proposal + ++++ https://github.com/cosmos/cosmos-sdk/blob/4a129832eb16f37a89e97652a669f0cdc9196ca9/proto/cosmos/gov/v1beta2/gov.proto#L42-L52 + +A proposal will generally require more than just a set of messages to explain its +purpose but need some greater justification and allow a means for interested participants +to discuss and debate the proposal. In most cases, it is encouraged to have an off-chain +system that supports the on-chain governance process. To accommodate for this, a +proposal contains a special `metadata` field, an array of bytes, which can be used to +add context to the proposal. The `metadata` field allows custom use for networks, however, +it is expected that the field contain a URL or some form of CID using a system such as +[IPFS](https://docs.ipfs.io/concepts/content-addressing/). To support the case of +interoperability across networks, the SDK recommends that the `metadata` represents +the following `JSON` template: + +```json +{ + "title": "...", + "description": "...", + "forum": "...", // a link to the discussion platform (i.e. Discord) + "other": "..." // any extra data that doesn't correspond to the other fields +} +``` + +This makes it far easier for clients to support multiple networks. + +### Writing a module that uses governance + +There are many aspects of a chain, or of the individual modules that you may want to +use governance to perform such as changing various parameters. This is very simple +to do. First, write out your message types and `MsgServer` implementation. Add an +`authority` field to the keeper which will be populated in the constructor with the +governance module account: `govKeeper.GetGovernanceAccount().GetAddress()`. Then for +the methods in the `msg_server.go`, perform a check on the message that the signer +matches `authority`. This will prevent any user from executing that message. + ## Parameters and base types `Parameters` define the rules according to which votes are run. There can only @@ -72,48 +114,6 @@ This type is used in a temp map when tallying } ``` -## Proposals - -`Proposal` objects are used to account votes and generally track the proposal's state. They contain `Content` which denotes -what this proposal is about, and other fields, which are the mutable state of -the governance process. - -+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/gov/v1beta1/gov.proto#L55-L77 - -```go -type Content interface { - GetTitle() string - GetDescription() string - ProposalRoute() string - ProposalType() string - ValidateBasic() sdk.Error - String() string -} -``` - -The `Content` on a proposal is an interface which contains the information about -the `Proposal` such as the tile, description, and any notable changes. Also, this -`Content` type can by implemented by any module. The `Content`'s `ProposalRoute` -returns a string which must be used to route the `Content`'s `Handler` in the -governance keeper. This allows the governance keeper to execute proposal logic -implemented by any module. If a proposal passes, the handler is executed. Only -if the handler is successful does the state get persisted and the proposal finally -passes. Otherwise, the proposal is rejected. - -```go -type Handler func(ctx sdk.Context, content Content) sdk.Error -``` - -The `Handler` is responsible for actually executing the proposal and processing -any state changes specified by the proposal. It is executed only if a proposal -passes during `EndBlock`. - -We also mention a method to update the tally for a given proposal: - -```go - func (proposal Proposal) updateTally(vote byte, amount sdk.Dec) -``` - ## Stores _Stores are KVStores in the multi-store. The key to find the store is the first diff --git a/x/gov/spec/03_messages.md b/x/gov/spec/03_messages.md index 53d550bda6..541793fb78 100644 --- a/x/gov/spec/03_messages.md +++ b/x/gov/spec/03_messages.md @@ -18,7 +18,7 @@ set in the governance module. - Generate new `proposalID` - Create new `Proposal` -- Initialise `Proposals` attributes +- Initialise `Proposal`'s attributes - Decrease balance of sender by `InitialDeposit` - If `MinDeposit` is reached: - Push `proposalID` in `ProposalProcessingQueue` @@ -34,7 +34,7 @@ pseudocode. upon receiving txGovSubmitProposal from sender do if !correctlyFormatted(txGovSubmitProposal) - // check if proposal is correctly formatted. Includes fee payment. + // check if proposal is correctly formatted and the messages have routes to other modules. Includes fee payment. throw initialDeposit = txGovSubmitProposal.InitialDeposit diff --git a/x/gov/spec/07_client.md b/x/gov/spec/07_client.md index 66cab628f2..578d80ad22 100644 --- a/x/gov/spec/07_client.md +++ b/x/gov/spec/07_client.md @@ -135,10 +135,14 @@ simd query gov proposal 1 Example Output: ```bash -content: - '@type': /cosmos.gov.v1beta1.TextProposal - description: testing, testing, 1, 2, 3 - title: Test Proposal +messages: [ + { + '@type': /cosmos.bank.v1beta1.MsgSend + from_address: "cosmos1..", + to_address: "cosmos1..", + amount: "100atom" + } +], deposit_end_time: "2021-09-17T23:36:18.254995423Z" final_tally_result: abstain: "0"