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

R4R: Query Gov Params #2576

Merged
merged 18 commits into from
Nov 13, 2018
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
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
6 changes: 6 additions & 0 deletions PENDING.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,16 @@ BREAKING CHANGES
FEATURES

* Gaia REST API (`gaiacli advanced rest-server`)
* [gov] [\#2479](https://github.com/cosmos/cosmos-sdk/issues/2479) Added governance parameter
query REST endpoints.

* Gaia CLI (`gaiacli`)
* [gov][cli] [\#2479](https://github.com/cosmos/cosmos-sdk/issues/2479) Added governance
parameter query commands.

* Gaia
* [x/gov] [#2479](https://github.com/cosmos/cosmos-sdk/issues/2479) Implemented querier
for getting governance parameters.

* SDK

Expand Down
47 changes: 42 additions & 5 deletions client/lcd/lcd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -730,26 +730,33 @@ func TestProposalsQuery(t *testing.T) {
cleanup, _, _, port := InitializeTestLCD(t, 1, []sdk.AccAddress{addrs[0], addrs[1]})
defer cleanup()

depositParam := getDepositParam(t, port)
halfMinDeposit := depositParam.MinDeposit.AmountOf("steak").Int64() / 2
getVotingParam(t, port)
getTallyingParam(t, port)

// Addr1 proposes (and deposits) proposals #1 and #2
resultTx := doSubmitProposal(t, port, seeds[0], names[0], passwords[0], addrs[0], 5)
resultTx := doSubmitProposal(t, port, seeds[0], names[0], passwords[0], addrs[0], halfMinDeposit)
var proposalID1 uint64
cdc.MustUnmarshalBinaryLengthPrefixed(resultTx.DeliverTx.GetData(), &proposalID1)
tests.WaitForHeight(resultTx.Height+1, port)
resultTx = doSubmitProposal(t, port, seeds[0], names[0], passwords[0], addrs[0], 5)

resultTx = doSubmitProposal(t, port, seeds[0], names[0], passwords[0], addrs[0], halfMinDeposit)
var proposalID2 uint64
cdc.MustUnmarshalBinaryLengthPrefixed(resultTx.DeliverTx.GetData(), &proposalID2)
tests.WaitForHeight(resultTx.Height+1, port)

// Addr2 proposes (and deposits) proposals #3
resultTx = doSubmitProposal(t, port, seeds[1], names[1], passwords[1], addrs[1], 5)
resultTx = doSubmitProposal(t, port, seeds[1], names[1], passwords[1], addrs[1], halfMinDeposit)
var proposalID3 uint64
cdc.MustUnmarshalBinaryLengthPrefixed(resultTx.DeliverTx.GetData(), &proposalID3)
tests.WaitForHeight(resultTx.Height+1, port)

// Addr2 deposits on proposals #2 & #3
resultTx = doDeposit(t, port, seeds[1], names[1], passwords[1], addrs[1], proposalID2, 5)
resultTx = doDeposit(t, port, seeds[1], names[1], passwords[1], addrs[1], proposalID2, halfMinDeposit)
tests.WaitForHeight(resultTx.Height+1, port)
resultTx = doDeposit(t, port, seeds[1], names[1], passwords[1], addrs[1], proposalID3, 5)

resultTx = doDeposit(t, port, seeds[1], names[1], passwords[1], addrs[1], proposalID3, halfMinDeposit)
tests.WaitForHeight(resultTx.Height+1, port)

// check deposits match proposal and individual deposits
Expand Down Expand Up @@ -1230,6 +1237,36 @@ func getValidatorRedelegations(t *testing.T, port string, validatorAddr sdk.ValA

// ============= Governance Module ================

func getDepositParam(t *testing.T, port string) gov.DepositParams {
res, body := Request(t, port, "GET", "/gov/parameters/deposit", nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)

var depositParams gov.DepositParams
err := cdc.UnmarshalJSON([]byte(body), &depositParams)
require.Nil(t, err)
return depositParams
}

func getVotingParam(t *testing.T, port string) gov.VotingParams {
res, body := Request(t, port, "GET", "/gov/parameters/voting", nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)

var votingParams gov.VotingParams
err := cdc.UnmarshalJSON([]byte(body), &votingParams)
require.Nil(t, err)
return votingParams
}

func getTallyingParam(t *testing.T, port string) gov.TallyParams {
res, body := Request(t, port, "GET", "/gov/parameters/tallying", nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)

var tallyParams gov.TallyParams
err := cdc.UnmarshalJSON([]byte(body), &tallyParams)
require.Nil(t, err)
return tallyParams
}

func getProposal(t *testing.T, port string, proposalID uint64) gov.Proposal {
res, body := Request(t, port, "GET", fmt.Sprintf("/gov/proposals/%d", proposalID), nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)
Expand Down
79 changes: 78 additions & 1 deletion client/lcd/swagger-ui/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1427,7 +1427,7 @@ paths:
/gov/proposals/{proposalId}/votes/{voter}:
get:
summary: Query vote
description: Query vote information by proposalId and voter address
description: Query vote information by proposal Id and voter address
produces:
- application/json
tags:
Expand All @@ -1454,6 +1454,83 @@ paths:
description: Found no vote
500:
description: Internal Server Error
/gov/parameters/deposit:
get:
summary: Query governance deposit parameters
description: Query governance deposit parameters. The max_deposit_period units are in nanoseconds.
produces:
- application/json
tags:
- ICS22
responses:
200:
description: OK
schema:
type: object
properties:
min_deposit:
type: array
items:
$ref: "#/definitions/Coin"
max_deposit_period:
type: string
example: "86400000000000"
400:
description: <other_path> is not a valid query request path
404:
description: Found no deposit parameters
500:
description: Internal Server Error
/gov/parameters/tallying:
get:
summary: Query governance tally parameters
description: Query governance tally parameters
produces:
- application/json
tags:
- ICS22
responses:
200:
description: OK
schema:
properties:
threshold:
type: string
example: "0.5000000000"
veto:
type: string
example: "0.3340000000"
governance_penalty:
type: string
example: "0.0100000000"
400:
description: <other_path> is not a valid query request path
404:
description: Found no tally parameters
500:
description: Internal Server Error
/gov/parameters/voting:
get:
summary: Query governance voting parameters
description: Query governance voting parameters. The voting_period units are in nanoseconds.
produces:
- application/json
tags:
- ICS22
responses:
200:
description: OK
schema:
properties:
voting_period:
type: string
example: "86400000000000"
400:
description: <other_path> is not a valid query request path
404:
description: Found no voting parameters
500:
description: Internal Server Error

definitions:
CheckTxResult:
Expand Down
31 changes: 31 additions & 0 deletions cmd/gaia/cli_test/cli_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,10 @@ func TestGaiaCLISubmitProposal(t *testing.T) {
tests.WaitForTMStart(port)
tests.WaitForNextNBlocksTM(2, port)

executeGetDepositParam(t, fmt.Sprintf("gaiacli query param deposit %v", flags))
executeGetVotingParam(t, fmt.Sprintf("gaiacli query param voting %v", flags))
executeGetTallyingParam(t, fmt.Sprintf("gaiacli query param tallying %v", flags))

fooAddr, _ := executeGetAddrPK(t, fmt.Sprintf("gaiacli keys show foo --output=json --home=%s", gaiacliHome))

fooAcc := executeGetAccount(t, fmt.Sprintf("gaiacli query account %s %v", fooAddr, flags))
Expand Down Expand Up @@ -771,6 +775,33 @@ func executeGetParams(t *testing.T, cmdStr string) stake.Params {
//___________________________________________________________________________________
// gov

func executeGetDepositParam(t *testing.T, cmdStr string) gov.DepositParams {
out, _ := tests.ExecuteT(t, cmdStr, "")
var depositParam gov.DepositParams
cdc := app.MakeCodec()
err := cdc.UnmarshalJSON([]byte(out), &depositParam)
require.NoError(t, err, "out %v\n, err %v", out, err)
return depositParam
}

func executeGetVotingParam(t *testing.T, cmdStr string) gov.VotingParams {
out, _ := tests.ExecuteT(t, cmdStr, "")
var votingParam gov.VotingParams
cdc := app.MakeCodec()
err := cdc.UnmarshalJSON([]byte(out), &votingParam)
require.NoError(t, err, "out %v\n, err %v", out, err)
return votingParam
}

func executeGetTallyingParam(t *testing.T, cmdStr string) gov.TallyParams {
out, _ := tests.ExecuteT(t, cmdStr, "")
var tallyingParam gov.TallyParams
cdc := app.MakeCodec()
err := cdc.UnmarshalJSON([]byte(out), &tallyingParam)
require.NoError(t, err, "out %v\n, err %v", out, err)
return tallyingParam
}

func executeGetProposal(t *testing.T, cmdStr string) gov.Proposal {
out, _ := tests.ExecuteT(t, cmdStr, "")
var proposal gov.Proposal
Expand Down
1 change: 1 addition & 0 deletions cmd/gaia/cmd/gaiacli/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ func main() {
stakecmd.GetCmdQueryValidatorRedelegations(queryRouteStake, cdc),
stakecmd.GetCmdQueryParams(storeStake, cdc),
stakecmd.GetCmdQueryPool(storeStake, cdc),
govcmd.GetCmdQueryParams(storeGov, cdc),
govcmd.GetCmdQueryProposal(storeGov, cdc),
govcmd.GetCmdQueryProposals(storeGov, cdc),
govcmd.GetCmdQueryVote(storeGov, cdc),
Expand Down
4 changes: 2 additions & 2 deletions docs/spec/governance/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:

Expand All @@ -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)**
Expand Down
51 changes: 25 additions & 26 deletions docs/spec/governance/state.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
alexanderbez marked this conversation as resolved.
Show resolved Hide resolved

`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:

Expand Down Expand Up @@ -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
)
```

Expand All @@ -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 {
Expand All @@ -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 {
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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

Expand All @@ -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
Expand All @@ -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

Expand Down
Loading