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: Switch gov proposal-queues to use iterators #2638

Merged
merged 17 commits into from
Nov 7, 2018
Merged
Show file tree
Hide file tree
Changes from 6 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
1 change: 1 addition & 0 deletions PENDING.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ IMPROVEMENTS
* Gaia CLI (`gaiacli`)

* Gaia
- #2637 [x/gov] Switched inactive and active proposal queues to an iterator based queue

* SDK
- \#2573 [x/distribution] add accum invariance
Expand Down
12 changes: 6 additions & 6 deletions client/lcd/lcd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -629,7 +629,7 @@ func TestSubmitProposal(t *testing.T) {
require.Equal(t, uint32(0), resultTx.DeliverTx.Code)

var proposalID int64
cdc.UnmarshalBinaryBare(resultTx.DeliverTx.GetData(), &proposalID)
cdc.MustUnmarshalBinaryLengthPrefixed(resultTx.DeliverTx.GetData(), &proposalID)

// query proposal
proposal := getProposal(t, port, proposalID)
Expand All @@ -651,7 +651,7 @@ func TestDeposit(t *testing.T) {
require.Equal(t, uint32(0), resultTx.DeliverTx.Code)

var proposalID int64
cdc.UnmarshalBinaryBare(resultTx.DeliverTx.GetData(), &proposalID)
cdc.MustUnmarshalBinaryLengthPrefixed(resultTx.DeliverTx.GetData(), &proposalID)

// query proposal
proposal := getProposal(t, port, proposalID)
Expand Down Expand Up @@ -685,7 +685,7 @@ func TestVote(t *testing.T) {
require.Equal(t, uint32(0), resultTx.DeliverTx.Code)

var proposalID int64
cdc.UnmarshalBinaryBare(resultTx.DeliverTx.GetData(), &proposalID)
cdc.MustUnmarshalBinaryLengthPrefixed(resultTx.DeliverTx.GetData(), &proposalID)

// query proposal
proposal := getProposal(t, port, proposalID)
Expand Down Expand Up @@ -733,17 +733,17 @@ func TestProposalsQuery(t *testing.T) {
// Addr1 proposes (and deposits) proposals #1 and #2
resultTx := doSubmitProposal(t, port, seeds[0], names[0], passwords[0], addrs[0], 5)
var proposalID1 int64
cdc.UnmarshalBinaryBare(resultTx.DeliverTx.GetData(), &proposalID1)
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)
var proposalID2 int64
cdc.UnmarshalBinaryBare(resultTx.DeliverTx.GetData(), &proposalID2)
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)
var proposalID3 int64
cdc.UnmarshalBinaryBare(resultTx.DeliverTx.GetData(), &proposalID3)
cdc.MustUnmarshalBinaryLengthPrefixed(resultTx.DeliverTx.GetData(), &proposalID3)
tests.WaitForHeight(resultTx.Height+1, port)

// Addr2 deposits on proposals #2 & #3
Expand Down
45 changes: 14 additions & 31 deletions docs/spec/governance/state.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,13 @@ type Proposal struct {
Type ProposalType // Type of proposal. Initial set {PlainTextProposal, SoftwareUpgradeProposal}
TotalDeposit sdk.Coins // Current deposit on this proposal. Initial value is set at InitialDeposit
Deposits []Deposit // List of deposits on the proposal
SubmitTime time.Time // Time of the block where TxGovSubmitProposal was included
Submitter sdk.Address // Address of the submitter
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.Address // Address of the submitter
sunnya97 marked this conversation as resolved.
Show resolved Hide resolved

VotingStartTime time.Time // Time of the block where MinDeposit was reached. time.Time{} if MinDeposit is not reached
CurrentStatus ProposalStatus // Current status of the proposal
VotingEndTime time.Time // Time of the block that the VotingPeriod for a proposal will end.
CurrentStatus ProposalStatus // Current status of the proposal

YesVotes sdk.Dec
NoVotes sdk.Dec
Expand Down Expand Up @@ -134,47 +136,29 @@ For pseudocode purposes, here are the two function we will use to read or write

**Store:**
* `ProposalProcessingQueue`: A queue `queue[proposalID]` containing all the
`ProposalIDs` of proposals that reached `MinDeposit`. Each round, the oldest
element of `ProposalProcessingQueue` is checked during `BeginBlock` to see if
`CurrentTime == VotingStartTime + activeProcedure.VotingPeriod`. If it is,
then the application tallies the votes, compute the votes of each validator and checks if every validator in the valdiator set have voted
and, if not, applies `GovernancePenalty`. If the proposal is accepted, deposits are refunded.
After that proposal is ejected from `ProposalProcessingQueue` and the next element of the queue is evaluated.
`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
each validator and checks if every validator in the valdiator set have voted.
If the proposal is accepted, deposits are refunded.

And the pseudocode for the `ProposalProcessingQueue`:

```go
in EndBlock do

checkProposal() // First call of the recursive function


// Recursive function. First call in BeginBlock
func checkProposal()
proposalID = ProposalProcessingQueue.Peek()
if (proposalID == nil)
return

proposal = load(Governance, <proposalID|'proposal'>) // proposal is a const key
votingProcedure = load(GlobalParams, 'VotingProcedure')
Copy link
Contributor

Choose a reason for hiding this comment

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

This isn't used.


for finishedProposalID in GetAllFinishedProposalIDs(block.Time)
proposal = load(Governance, <proposalID|'proposal'>) // proposal is a const key

if (CurrentTime == proposal.VotingStartTime + votingProcedure.VotingPeriod && proposal.CurrentStatus == ProposalStatusActive)

// End of voting period, tally

ProposalProcessingQueue.pop()
validators =


Keeper.getAllValidators()
validators = Keeper.getAllValidators()
tmpValMap := map(sdk.Address)ValidatorGovInfo
Copy link
Contributor

Choose a reason for hiding this comment

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

s/sdk.Address/sdk.ValAddress/g


// Initiate mapping at 0. Validators that remain at 0 at the end of tally will be punished
Copy link
Contributor

Choose a reason for hiding this comment

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

This comment (as well as the comment in the code) don't make sense... This comment makes it sound like .Minus being 0 means the validator will be punished, but that's not it.... right?

It seems that Minus should be called DelegatorOverrideShares

for each validator in validators
tmpValMap(validator).Minus = 0



// Tally
voterIterator = rangeQuery(Governance, <proposalID|'addresses'>) //return all the addresses that voted on the proposal
for each (voterAddress, vote) in voterIterator
Expand Down Expand Up @@ -212,5 +196,4 @@ And the pseudocode for the `ProposalProcessingQueue`:
proposal.CurrentStatus = ProposalStatusRejected

store(Governance, <proposalID|'proposal'>, proposal)
checkProposal()
```
8 changes: 8 additions & 0 deletions types/utils.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package types

import (
"encoding/binary"
"encoding/json"
"time"

Expand Down Expand Up @@ -36,6 +37,13 @@ func MustSortJSON(toSortJSON []byte) []byte {
return js
}

// Uint64ToBigEndian - marshals uint64 to a bigendian byte slice so it can be sorted
func Uint64ToBigEndian(i uint64) []byte {
b := make([]byte, 8)
binary.BigEndian.PutUint64(b, i)
return b
}

// Slight modification of the RFC3339Nano but it right pads all zeros and drops the time zone info
const SortableTimeFormat = "2006-01-02T15:04:05.000000000"

Expand Down
Loading