Sunnys feedback
This commit is contained in:
parent
6f8a2d562c
commit
8c800eb42a
|
@ -52,6 +52,7 @@ const (
|
||||||
ProposalStatusActive = 0x2 // MinDeposit is reachhed, participants can vote
|
ProposalStatusActive = 0x2 // MinDeposit is reachhed, participants can vote
|
||||||
ProposalStatusAccepted = 0x3 // Proposal has been accepted
|
ProposalStatusAccepted = 0x3 // Proposal has been accepted
|
||||||
ProposalStatusRejected = 0x4 // Proposal has been rejected
|
ProposalStatusRejected = 0x4 // Proposal has been rejected
|
||||||
|
ProposalStatusClosed. = 0x5 // Proposal never reached MinDeposit
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -90,7 +91,6 @@ type Proposal struct {
|
||||||
Submitter sdk.Address // Address of the submitter
|
Submitter sdk.Address // Address of the submitter
|
||||||
|
|
||||||
VotingStartBlock int64 // Height of the block where MinDeposit was reached. -1 if MinDeposit is not reached
|
VotingStartBlock int64 // Height of the block where MinDeposit was reached. -1 if MinDeposit is not reached
|
||||||
InitProcedure Procedure // Active Procedure when proposal enters voting period
|
|
||||||
CurrentStatus ProposalStatus // Current status of the proposal
|
CurrentStatus ProposalStatus // Current status of the proposal
|
||||||
|
|
||||||
YesVotes sdk.Rat
|
YesVotes sdk.Rat
|
||||||
|
@ -112,8 +112,8 @@ We also mention a method to update the tally for a given proposal:
|
||||||
|
|
||||||
We will use one KVStore `Governance` to store two mappings:
|
We will use one KVStore `Governance` to store two mappings:
|
||||||
|
|
||||||
* A mapping from `proposalID` to `Proposal`
|
* A mapping from `proposalID|'proposal'` to `Proposal`
|
||||||
* A mapping from `proposalID:addresses:address` to `Vote`. This mapping allows us to query all addresses that voted on the proposal along with their vote by doing a range query on `proposalID:addresses`
|
* A mapping from `proposalID|'addresses'|address` to `Vote`. This mapping allows us to query all addresses that voted on the proposal along with their vote by doing a range query on `proposalID:addresses`
|
||||||
|
|
||||||
|
|
||||||
For pseudocode purposes, here are the two function we will use to read or write in stores:
|
For pseudocode purposes, here are the two function we will use to read or write in stores:
|
||||||
|
@ -127,7 +127,7 @@ For pseudocode purposes, here are the two function we will use to read or write
|
||||||
* `ProposalProcessingQueue`: A queue `queue[proposalID]` containing all the
|
* `ProposalProcessingQueue`: A queue `queue[proposalID]` containing all the
|
||||||
`ProposalIDs` of proposals that reached `MinDeposit`. Each round, the oldest
|
`ProposalIDs` of proposals that reached `MinDeposit`. Each round, the oldest
|
||||||
element of `ProposalProcessingQueue` is checked during `BeginBlock` to see if
|
element of `ProposalProcessingQueue` is checked during `BeginBlock` to see if
|
||||||
`CurrentBlock == VotingStartBlock + InitProcedure.VotingPeriod`. If it is,
|
`CurrentBlock == VotingStartBlock + 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
|
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.
|
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.
|
After that proposal is ejected from `ProposalProcessingQueue` and the next element of the queue is evaluated.
|
||||||
|
@ -146,9 +146,10 @@ And the pseudocode for the `ProposalProcessingQueue`:
|
||||||
if (proposalID == nil)
|
if (proposalID == nil)
|
||||||
return
|
return
|
||||||
|
|
||||||
proposal = load(Governance, proposalID)
|
proposal = load(Governance, <proposalID|'proposal'>) // proposal is a const key
|
||||||
|
activeProcedure = load(params, 'ActiveProcedure')
|
||||||
|
|
||||||
if (CurrentBlock == proposal.VotingStartBlock + proposal.Procedure.VotingPeriod && proposal.CurrentStatus == ProposalStatusActive)
|
if (CurrentBlock == proposal.VotingStartBlock + activeProcedure.VotingPeriod && proposal.CurrentStatus == ProposalStatusActive)
|
||||||
|
|
||||||
// End of voting period, tally
|
// End of voting period, tally
|
||||||
|
|
||||||
|
@ -163,7 +164,7 @@ And the pseudocode for the `ProposalProcessingQueue`:
|
||||||
|
|
||||||
|
|
||||||
// Tally
|
// Tally
|
||||||
voterIterator = rangeQuery(Governance, <proposalID|addresses>) //return all the addresses that voted on the proposal
|
voterIterator = rangeQuery(Governance, <proposalID|'addresses'>) //return all the addresses that voted on the proposal
|
||||||
for each (voterAddress, vote) in voterIterator
|
for each (voterAddress, vote) in voterIterator
|
||||||
delegations = stakeKeeper.getDelegations(voterAddress) // get all delegations for current voter
|
delegations = stakeKeeper.getDelegations(voterAddress) // get all delegations for current voter
|
||||||
|
|
||||||
|
@ -188,7 +189,7 @@ And the pseudocode for the `ProposalProcessingQueue`:
|
||||||
|
|
||||||
// Check if proposal is accepted or rejected
|
// Check if proposal is accepted or rejected
|
||||||
totalNonAbstain := proposal.YesVotes + proposal.NoVotes + proposal.NoWithVetoVotes
|
totalNonAbstain := proposal.YesVotes + proposal.NoVotes + proposal.NoWithVetoVotes
|
||||||
if (proposal.Votes.YesVotes/totalNonAbstain > proposal.InitProcedure.Threshold AND proposal.Votes.NoWithVetoVotes/totalNonAbstain < proposal.InitProcedure.Veto)
|
if (proposal.Votes.YesVotes/totalNonAbstain > activeProcedure.Threshold AND proposal.Votes.NoWithVetoVotes/totalNonAbstain < activeProcedure.Veto)
|
||||||
// proposal was accepted at the end of the voting period
|
// proposal was accepted at the end of the voting period
|
||||||
// refund deposits (non-voters already punished)
|
// refund deposits (non-voters already punished)
|
||||||
proposal.CurrentStatus = ProposalStatusAccepted
|
proposal.CurrentStatus = ProposalStatusAccepted
|
||||||
|
@ -199,6 +200,6 @@ And the pseudocode for the `ProposalProcessingQueue`:
|
||||||
// proposal was rejected
|
// proposal was rejected
|
||||||
proposal.CurrentStatus = ProposalStatusRejected
|
proposal.CurrentStatus = ProposalStatusRejected
|
||||||
|
|
||||||
store(Governance, proposalID, proposal)
|
store(Governance, <proposalID|'proposal'>, proposal)
|
||||||
checkProposal()
|
checkProposal()
|
||||||
```
|
```
|
||||||
|
|
|
@ -65,17 +65,15 @@ upon receiving txGovSubmitProposal from sender do
|
||||||
// MinDeposit is not reached
|
// MinDeposit is not reached
|
||||||
|
|
||||||
proposal.CurrentStatus = ProposalStatusOpen
|
proposal.CurrentStatus = ProposalStatusOpen
|
||||||
proposal.VotingStartBlock = -1
|
|
||||||
|
|
||||||
else
|
else
|
||||||
// MinDeposit is reached
|
// MinDeposit is reached
|
||||||
|
|
||||||
proposal.CurrentStatus = ProposalStatusActive
|
proposal.CurrentStatus = ProposalStatusActive
|
||||||
proposal.VotingStartBlock = CurrentBlock
|
proposal.VotingStartBlock = CurrentBlock
|
||||||
proposal.InitProcedure = activeProcedure
|
|
||||||
ProposalProcessingQueue.push(proposalID)
|
ProposalProcessingQueue.push(proposalID)
|
||||||
|
|
||||||
store(Proposals, proposalID, proposal) // Store proposal in Proposals mapping
|
store(Proposals, <proposalID|'proposal'>, proposal) // Store proposal in Proposals mapping
|
||||||
return proposalID
|
return proposalID
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -112,7 +110,7 @@ upon receiving txGovDeposit from sender do
|
||||||
if !correctlyFormatted(txGovDeposit)
|
if !correctlyFormatted(txGovDeposit)
|
||||||
throw
|
throw
|
||||||
|
|
||||||
proposal = load(Proposals, txGovDeposit.ProposalID)
|
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
|
// There is no proposal for this proposalID
|
||||||
|
@ -120,29 +118,32 @@ upon receiving txGovDeposit from sender do
|
||||||
|
|
||||||
activeProcedure = load(params, 'ActiveProcedure')
|
activeProcedure = load(params, 'ActiveProcedure')
|
||||||
|
|
||||||
if (txGovDeposit.Deposit.Atoms <= 0) OR (sender.AtomBalance < txGovDeposit.Deposit.Atoms) OR (proposal.TotalDeposit >= activeProcedure.MinDeposit) OR (CurrentBlock >= proposal.SubmitBlock + activeProcedure.MaxDepositPeriod)
|
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 sender has insufficient funds
|
||||||
// OR minDeposit has already been reached
|
// OR proposal is not open for deposit anymore
|
||||||
// OR Maximum deposit period reached
|
|
||||||
|
|
||||||
throw
|
throw
|
||||||
|
|
||||||
// sender can deposit
|
if (CurrentBlock >= proposal.SubmitBlock + activeProcedure.MaxDepositPeriod)
|
||||||
sender.AtomBalance -= txGovDeposit.Deposit.Atoms
|
proposal.CurrentStatus = ProposalStatusClosed
|
||||||
|
|
||||||
proposal.Deposits.append({txGovVote.Deposit, sender})
|
else
|
||||||
proposal.TotalDeposit.Plus(txGovDeposit.Deposit)
|
// sender can deposit
|
||||||
|
sender.AtomBalance -= txGovDeposit.Deposit.Atoms
|
||||||
|
|
||||||
if (proposal.TotalDeposit >= activeProcedure.MinDeposit)
|
proposal.Deposits.append({txGovVote.Deposit, sender})
|
||||||
// MinDeposit is reached, vote opens
|
proposal.TotalDeposit.Plus(txGovDeposit.Deposit)
|
||||||
|
|
||||||
proposal.VotingStartBlock = CurrentBlock
|
if (proposal.TotalDeposit >= activeProcedure.MinDeposit)
|
||||||
proposal.CurrentStatus = ProposalStatusActive
|
// MinDeposit is reached, vote opens
|
||||||
proposal.InitProcedure = activeProcedure
|
|
||||||
ProposalProcessingQueue.push(txGovDeposit.ProposalID)
|
|
||||||
|
|
||||||
store(Proposals, txGovVote.ProposalID, proposal)
|
proposal.VotingStartBlock = CurrentBlock
|
||||||
|
proposal.CurrentStatus = ProposalStatusActive
|
||||||
|
ProposalProcessingQueue.push(txGovDeposit.ProposalID)
|
||||||
|
|
||||||
|
store(Proposals, <txGovVote.ProposalID|'proposal'>, proposal)
|
||||||
```
|
```
|
||||||
|
|
||||||
### Vote
|
### Vote
|
||||||
|
@ -153,7 +154,7 @@ vote on the proposal.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
type TxGovVote struct {
|
type TxGovVote struct {
|
||||||
ProposalID int64 // proposalID of the proposal
|
ProposalID int64 // proposalID of the proposal
|
||||||
Vote byte // option from OptionSet chosen by the voter
|
Vote byte // option from OptionSet chosen by the voter
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
@ -176,21 +177,18 @@ handled:
|
||||||
if !correctlyFormatted(txGovDeposit)
|
if !correctlyFormatted(txGovDeposit)
|
||||||
throw
|
throw
|
||||||
|
|
||||||
proposal = load(Proposals, txGovDeposit.ProposalID)
|
proposal = load(Proposals, <txGovDeposit.ProposalID|'proposal'>)
|
||||||
|
|
||||||
if (proposal == nil)
|
if (proposal == nil)
|
||||||
// There is no proposal for this proposalID
|
// There is no proposal for this proposalID
|
||||||
throw
|
throw
|
||||||
|
|
||||||
|
|
||||||
if (proposal.VotingStartBlock >= 0) AND
|
if (proposal.CurrentStatus == ProposalStatusActive)
|
||||||
(CurrentBlock <= proposal.VotingStartBlock + proposal.InitProcedure.VotingPeriod)
|
|
||||||
|
|
||||||
// Sender can vote if
|
// Sender can vote
|
||||||
// Vote has started AND if
|
|
||||||
// Vote had notended
|
|
||||||
|
|
||||||
store(Governance, <txGovVote.ProposalID|addresses|sender>, txGovVote.Vote) // Voters can vote multiple times. Re-voting overrides previous vote. This is ok because tallying is done once at the end.
|
store(Governance, <txGovVote.ProposalID|'addresses'|sender>, txGovVote.Vote) // Voters can vote multiple times. Re-voting overrides previous vote. This is ok because tallying is done once at the end.
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
Loading…
Reference in New Issue