R4R: Query Gov Params (#2576)

* gov query params
This commit is contained in:
Sunny Aggarwal
2018-11-13 15:45:37 -08:00
committed by Jack Zampolin
parent d184121ea0
commit d1614ebb7e
18 changed files with 673 additions and 90 deletions
+2 -2
View File
@@ -2,7 +2,7 @@
## Abstract
This paper specifies the Governance module of the Cosmos-SDK, which was first described in the [Cosmos Whitepaper](https://cosmos.network/about/whitepaper) in June 2016.
This paper specifies the Governance module of the Cosmos-SDK, which was first described in the [Cosmos Whitepaper](https://cosmos.network/about/whitepaper) in June 2016.
The module enables Cosmos-SDK based blockchain to support an on-chain governance system. In this system, holders of the native staking token of the chain can vote on proposals on a 1 token 1 vote basis. Next is a list of features the module currently supports:
@@ -24,7 +24,7 @@ The following specification uses *Atom* as the native staking token. The module
1. **[Design overview](overview.md)**
2. **Implementation**
1. **[State](state.md)**
1. Procedures
1. Parameters
2. Proposals
3. Proposal Processing Queue
2. **[Transactions](transactions.md)**
+25 -26
View File
@@ -2,36 +2,35 @@
## State
### Procedures and base types
`Procedures` define the rule according to which votes are run. There can only
be one active procedure at any given time. If governance wants to change a
procedure, either to modify a value or add/remove a parameter, a new procedure
has to be created and the previous one rendered inactive.
### Parameters and base types
`Parameters` define the rules according to which votes are run. There can only
be one active parameter set at any given time. If governance wants to change a
parameter set, either to modify a value or add/remove a parameter field, a new
parameter set has to be created and the previous one rendered inactive.
```go
type DepositProcedure struct {
MinDeposit sdk.Coins // Minimum deposit for a proposal to enter voting period.
MaxDepositPeriod time.Time // Maximum period for Atom holders to deposit on a proposal. Initial value: 2 months
type DepositParams struct {
MinDeposit sdk.Coins // Minimum deposit for a proposal to enter voting period.
MaxDepositPeriod time.Time // Maximum period for Atom holders to deposit on a proposal. Initial value: 2 months
}
```
```go
type VotingProcedure struct {
VotingPeriod time.Time // Length of the voting period. Initial value: 2 weeks
type VotingParams struct {
VotingPeriod time.Time // Length of the voting period. Initial value: 2 weeks
}
```
```go
type TallyingProcedure struct {
Threshold sdk.Dec // Minimum propotion of Yes votes for proposal to pass. Initial value: 0.5
Veto sdk.Dec // Minimum proportion of Veto votes to Total votes ratio for proposal to be vetoed. Initial value: 1/3
GovernancePenalty sdk.Dec // Penalty if validator does not vote
type TallyParams struct {
Threshold sdk.Dec // Minimum proportion of Yes votes for proposal to pass. Initial value: 0.5
Veto sdk.Dec // Minimum proportion of Veto votes to Total votes ratio for proposal to be vetoed. Initial value: 1/3
GovernancePenalty sdk.Dec // Penalty if validator does not vote
}
```
Procedures are stored in a global `GlobalParams` KVStore.
Parameters are stored in a global `GlobalParams` KVStore.
Additionally, we introduce some basic types:
@@ -61,7 +60,7 @@ const (
ProposalStatusActive = 0x2 // MinDeposit is reachhed, participants can vote
ProposalStatusAccepted = 0x3 // Proposal has been accepted
ProposalStatusRejected = 0x4 // Proposal has been rejected
ProposalStatusClosed. = 0x5 // Proposal never reached MinDeposit
ProposalStatusClosed = 0x5 // Proposal never reached MinDeposit
)
```
@@ -76,7 +75,7 @@ const (
### ValidatorGovInfo
This type is used in a temp map when tallying
This type is used in a temp map when tallying
```go
type ValidatorGovInfo struct {
@@ -87,7 +86,7 @@ This type is used in a temp map when tallying
### Proposals
`Proposals` are an item to be voted on.
`Proposals` are an item to be voted on.
```go
type Proposal struct {
@@ -99,7 +98,7 @@ type Proposal struct {
SubmitTime time.Time // Time of the block where TxGovSubmitProposal was included
DepositEndTime time.Time // Time that the DepositPeriod of a proposal would expire
Submitter sdk.AccAddress // Address of the submitter
VotingStartTime time.Time // Time of the block where MinDeposit was reached. time.Time{} if MinDeposit is not reached
VotingEndTime time.Time // Time of the block that the VotingPeriod for a proposal will end.
CurrentStatus ProposalStatus // Current status of the proposal
@@ -135,7 +134,7 @@ For pseudocode purposes, here are the two function we will use to read or write
### Proposal Processing Queue
**Store:**
* `ProposalProcessingQueue`: A queue `queue[proposalID]` containing all the
* `ProposalProcessingQueue`: A queue `queue[proposalID]` containing all the
`ProposalIDs` of proposals that reached `MinDeposit`. Each `EndBlock`, all the proposals
that have reached the end of their voting period are processed.
To process a finished proposal, the application tallies the votes, compute the votes of
@@ -145,8 +144,8 @@ For pseudocode purposes, here are the two function we will use to read or write
And the pseudocode for the `ProposalProcessingQueue`:
```go
in EndBlock do
in EndBlock do
for finishedProposalID in GetAllFinishedProposalIDs(block.Time)
proposal = load(Governance, <proposalID|'proposal'>) // proposal is a const key
@@ -171,7 +170,7 @@ And the pseudocode for the `ProposalProcessingQueue`:
if (isVal)
tmpValMap(voterAddress).Vote = vote
tallyingProcedure = load(GlobalParams, 'TallyingProcedure')
tallyingParam = load(GlobalParams, 'TallyingParam')
// Update tally if validator voted they voted
for each validator in validators
@@ -182,14 +181,14 @@ And the pseudocode for the `ProposalProcessingQueue`:
// Check if proposal is accepted or rejected
totalNonAbstain := proposal.YesVotes + proposal.NoVotes + proposal.NoWithVetoVotes
if (proposal.Votes.YesVotes/totalNonAbstain > tallyingProcedure.Threshold AND proposal.Votes.NoWithVetoVotes/totalNonAbstain < tallyingProcedure.Veto)
if (proposal.Votes.YesVotes/totalNonAbstain > tallyingParam.Threshold AND proposal.Votes.NoWithVetoVotes/totalNonAbstain < tallyingParam.Veto)
// proposal was accepted at the end of the voting period
// refund deposits (non-voters already punished)
proposal.CurrentStatus = ProposalStatusAccepted
for each (amount, depositer) in proposal.Deposits
depositer.AtomBalance += amount
else
else
// proposal was rejected
proposal.CurrentStatus = ProposalStatusRejected
+38 -38
View File
@@ -4,7 +4,7 @@
### Proposal Submission
Proposals can be submitted by any Atom holder via a `TxGovSubmitProposal`
Proposals can be submitted by any Atom holder via a `TxGovSubmitProposal`
transaction.
```go
@@ -24,7 +24,7 @@ type TxGovSubmitProposal struct {
* If `MinDeposit` is reached:
* Push `proposalID` in `ProposalProcessingQueue`
A `TxGovSubmitProposal` transaction can be handled according to the following
A `TxGovSubmitProposal` transaction can be handled according to the following
pseudocode.
```go
@@ -32,31 +32,31 @@ pseudocode.
// Check if TxGovSubmitProposal is valid. If it is, create proposal //
upon receiving txGovSubmitProposal from sender do
if !correctlyFormatted(txGovSubmitProposal)
if !correctlyFormatted(txGovSubmitProposal)
// check if proposal is correctly formatted. Includes fee payment.
throw
initialDeposit = txGovSubmitProposal.InitialDeposit
if (initialDeposit.Atoms <= 0) OR (sender.AtomBalance < initialDeposit.Atoms)
initialDeposit = txGovSubmitProposal.InitialDeposit
if (initialDeposit.Atoms <= 0) OR (sender.AtomBalance < initialDeposit.Atoms)
// InitialDeposit is negative or null OR sender has insufficient funds
throw
if (txGovSubmitProposal.Type != ProposalTypePlainText) OR (txGovSubmitProposal.Type != ProposalTypeSoftwareUpgrade)
sender.AtomBalance -= initialDeposit.Atoms
depositProcedure = load(GlobalParams, 'DepositProcedure')
depositParam = load(GlobalParams, 'DepositParam')
proposalID = generate new proposalID
proposal = NewProposal()
proposal.Title = txGovSubmitProposal.Title
proposal.Description = txGovSubmitProposal.Description
proposal.Type = txGovSubmitProposal.Type
proposal.TotalDeposit = initialDeposit
proposal.SubmitTime = <CurrentTime>
proposal.DepositEndTime = <CurrentTime>.Add(depositProcedure.MaxDepositPeriod)
proposal.DepositEndTime = <CurrentTime>.Add(depositParam.MaxDepositPeriod)
proposal.Deposits.append({initialDeposit, sender})
proposal.Submitter = sender
proposal.YesVotes = 0
@@ -64,15 +64,15 @@ upon receiving txGovSubmitProposal from sender do
proposal.NoWithVetoVotes = 0
proposal.AbstainVotes = 0
proposal.CurrentStatus = ProposalStatusOpen
store(Proposals, <proposalID|'proposal'>, proposal) // Store proposal in Proposals mapping
return proposalID
```
### Deposit
Once a proposal is submitted, if
`Proposal.TotalDeposit < ActiveProcedure.MinDeposit`, Atom holders can send
Once a proposal is submitted, if
`Proposal.TotalDeposit < ActiveParam.MinDeposit`, Atom holders can send
`TxGovDeposit` transactions to increase the proposal's deposit.
```go
@@ -89,7 +89,7 @@ type TxGovDeposit struct {
* If `MinDeposit` is reached:
* Push `proposalID` in `ProposalProcessingQueueEnd`
A `TxGovDeposit` transaction has to go through a number of checks to be valid.
A `TxGovDeposit` transaction has to go through a number of checks to be valid.
These checks are outlined in the following pseudocode.
```go
@@ -98,27 +98,27 @@ These checks are outlined in the following pseudocode.
upon receiving txGovDeposit from sender do
// check if proposal is correctly formatted. Includes fee payment.
if !correctlyFormatted(txGovDeposit)
if !correctlyFormatted(txGovDeposit)
throw
proposal = load(Proposals, <txGovDeposit.ProposalID|'proposal'>) // proposal is a const key, proposalID is variable
if (proposal == nil)
if (proposal == nil)
// There is no proposal for this proposalID
throw
if (txGovDeposit.Deposit.Atoms <= 0) OR (sender.AtomBalance < txGovDeposit.Deposit.Atoms) OR (proposal.CurrentStatus != ProposalStatusOpen)
// deposit is negative or null
// deposit is negative or null
// OR sender has insufficient funds
// OR proposal is not open for deposit anymore
throw
depositProcedure = load(GlobalParams, 'DepositProcedure')
depositParam = load(GlobalParams, 'DepositParam')
if (CurrentBlock >= proposal.SubmitBlock + depositProcedure.MaxDepositPeriod)
if (CurrentBlock >= proposal.SubmitBlock + depositParam.MaxDepositPeriod)
proposal.CurrentStatus = ProposalStatusClosed
else
@@ -127,21 +127,21 @@ upon receiving txGovDeposit from sender do
proposal.Deposits.append({txGovVote.Deposit, sender})
proposal.TotalDeposit.Plus(txGovDeposit.Deposit)
if (proposal.TotalDeposit >= depositProcedure.MinDeposit)
if (proposal.TotalDeposit >= depositParam.MinDeposit)
// MinDeposit is reached, vote opens
proposal.VotingStartBlock = CurrentBlock
proposal.CurrentStatus = ProposalStatusActive
ProposalProcessingQueue.push(txGovDeposit.ProposalID)
ProposalProcessingQueue.push(txGovDeposit.ProposalID)
store(Proposals, <txGovVote.ProposalID|'proposal'>, proposal)
```
### Vote
Once `ActiveProcedure.MinDeposit` is reached, voting period starts. From there,
bonded Atom holders are able to send `TxGovVote` transactions to cast their
Once `ActiveParam.MinDeposit` is reached, voting period starts. From there,
bonded Atom holders are able to send `TxGovVote` transactions to cast their
vote on the proposal.
```go
@@ -157,25 +157,25 @@ vote on the proposal.
*Note: Gas cost for this message has to take into account the future tallying of the vote in EndBlocker*
Next is a pseudocode proposal of the way `TxGovVote` transactions are
Next is a pseudocode proposal of the way `TxGovVote` transactions are
handled:
```go
// PSEUDOCODE //
// Check if TxGovVote is valid. If it is, count vote//
upon receiving txGovVote from sender do
// check if proposal is correctly formatted. Includes fee payment.
if !correctlyFormatted(txGovDeposit)
// check if proposal is correctly formatted. Includes fee payment.
if !correctlyFormatted(txGovDeposit)
throw
proposal = load(Proposals, <txGovDeposit.ProposalID|'proposal'>)
if (proposal == nil)
if (proposal == nil)
// There is no proposal for this proposalID
throw
if (proposal.CurrentStatus == ProposalStatusActive)