Small fixes

This commit is contained in:
gamarin 2018-02-21 17:45:23 +01:00
parent d0e458f3bc
commit dd0695afa0
1 changed files with 34 additions and 29 deletions

View File

@ -10,21 +10,21 @@ The governance process is divided in a few steps that are outlined below:
- **Proposal submission:** Proposal is submitted to the blockchain with a deposit
- **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:** Validator start signaling that they are ready to switch to the new version
- **Switch:** Once more than 2/3rd validators have signaled their readiness to switch, their software automatically flips to the new version
- 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
## Proposal submission
### Right to submit a proposal
Any Atom holder, whether bonded or unbonded, can submit proposals by sending a `TxProposal` transaction. Once a proposal is submitted, it is identified by its unique `proposalID`.
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`.
### Proposal filter (minimum deposit)
To prevent spam, proposals must be submitted with a deposit in Atoms. Voting period will not start as long as the proposal's deposit is smaller than the minimum deposit parameter `MinDeposit`.
To prevent spam, proposals must be submitted with a deposit in Atoms. Voting period will not start as long as the proposal's deposit is smaller than the minimum deposit `MinDeposit`.
When a proposal is submitted, it has to be accompagnied by a deposit that must be strictly positive but that can be inferior to `MinDeposit`. Indeed, the submitter need not pay for the entire deposit on its own. If a proposal's deposit is strictly inferior to `MinDeposit`, other Atom holders can increase the proposal's deposit by sending a `TxGovDeposit` transaction. Once the proposals's deposit reaches `minDeposit`, it enters voting period.
When a proposal is submitted, it has to be accompagnied by a deposit that must be strictly positive but can be inferior to `MinDeposit`. Indeed, the submitter need not pay for the entire deposit on its own. If a proposal's deposit is strictly inferior to `MinDeposit`, other Atom holders can increase the proposal's deposit by sending a `TxGovDeposit` transaction. Once the proposals's deposit reaches `MinDeposit`, it enters voting period.
### Deposit refund
@ -48,7 +48,6 @@ There are two categories of proposal:
These two categories are strictly identical except that `Urgent` proposals can be accepted faster if a certain condition is met. For more information, see [Threshold](#threshold) section.
## Vote
### Participants
@ -59,6 +58,8 @@ Note that some *participants* can be forbidden to vote on a proposal under a cer
- *participant* bonded or unbonded Atoms to said validator after proposal entered voting period
- *participant* became validator after proposal entered voting period
This does not prevent *participant* to vote with Atoms bonded to other validators. For example, if a *participant* bonded some Atoms to validator A before a proposal entered voting period and other Atoms to validator B after proposal entered voting period, only the vote under validator B will be forbidden.
### Voting period
Once a proposal reaches `MinDeposit`, it immediately enters `Voting period`. We define `Voting period` as the interval between the moment the vote opens and the moment the vote closes. `Voting period` should always be shorter than `Unbonding period` to prevent double voting. The initial value of `Voting period` is 2 weeks.
@ -96,13 +97,13 @@ Initially, the threshold is set at 50% with a possibility to veto if more than 1
If a delegator does not vote, it will inherit its validator vote.
- If the delegator votes before its validator, it will not inherit from the validator's vote.
- If the delegator votes after its validaotor, it will override its validator vote with its own vote. If the proposal is a `Urgent` proposal, it is possible that the vote will close before delegators have a chance to react and override their validator's vote. This is not a problem, as `Urgent` proposals require more than 2/3rd of the total voting power to pass before the end of the voting period. If more than 2/3rd of validators collude, they can censor the votes of delegators anyway.
- If the delegator votes after its validator, it will override its validator vote with its own. If the proposal is a `Urgent` proposal, it is possible that the vote will close before delegators have a chance to react and override their validator's vote. This is not a problem, as `Urgent` proposals require more than 2/3rd of the total voting power to pass before the end of the voting period. If more than 2/3rd of validators collude, they can censor the votes of delegators anyway.
### Validators punishment for non-voting
Validators are required to vote on all proposals to ensure that results have legitimacy. Voting is part of validators' directives and failure to do it will result in a penalty.
If a validators address is not in the list of addresses that voted on a proposal and if the vote is closed (i.e. `MinDeposit` was reached and `Voting period` is over), then this validator will automatically be partially slashed of `GovernancePenalty`.
If a validators address is not in the list of addresses that voted on a proposal and the vote is closed (i.e. `MinDeposit` was reached and `Voting period` is over), then the validator will automatically be partially slashed of `GovernancePenalty`.
*Note: Need to define values for `GovernancePenalty`*
@ -110,7 +111,7 @@ If a validators address is not in the list of addresses that voted on a propo
### Governance key and governance address
Validators can make use of an additional slot where they can designate a `Governance PubKey`. By default, a validator's `Governance PubKey` will be the same as its main PubKey. Validators can change this `Governance PubKey` by sending a `Change Governance PubKey` transaction signed by their main `Consensus PrivKey`. From there, they will be able to sign vote using the `Governance PrivKey` associated with their `Governance PubKey`. The `Governance PubKey` can be changed at any moment.
Validators can make use of a slot where they can designate a `Governance PubKey`. By default, a validator's `Governance PubKey` will be the same as its main PubKey. Validators can change this `Governance PubKey` by sending a `Change Governance PubKey` transaction signed by their main `Consensus PrivKey`. From there, they will be able to sign votes using the `Governance PrivKey` associated with their `Governance PubKey`. The `Governance PubKey` can be changed at any moment.
## Software Upgrade
@ -151,13 +152,13 @@ type Procedure struct {
MaxDepositPeriod int64 // Maximum period for Atom holders to deposit on a proposal. Initial value: 2 months
GovernancePenalty int64 // Penalty if validator does not vote
ProcedureNumber int16 // Incremented each time a new procedure is created
IsActive bool // If true, procedure is active. Only one procedure can have isActive true.
}
```
**Store**:
- `Procedures`: a mapping `map[int16]Procedure` of procedures indexed by their `ProcedureNumber`
- `ActiveProcedureNumber`: returns current procedure number
#### Proposals
@ -191,7 +192,7 @@ type ValidatorGovInfo struct {
**Store:**
- `Proposals`: A mapping `map[int64]Proposal` of proposals indexed by their `proposalID`
- `Deposits`: A mapping `map[[]byte]int64` of deposits indexed by `<proposalID>:<depositorPubKey>` as `[]byte`. Given a `proposalID` and a `PubKey`, returns deposit (`nil` if `PubKey` has not deposited)
- `Deposits`: A mapping `map[[]byte]int64` of deposits indexed by `<proposalID>:<depositorPubKey>` as `[]byte`. Given a `proposalID` and a `PubKey`, returns deposit (`nil` if `PubKey` has not deposited on the proposal)
- `Options`: A mapping `map[[]byte]string` of options indexed by `<proposalID>:<voterPubKey>:<validatorPubKey>` as `[]byte`. Given a `proposalID`, a `PubKey` and a validator's `PubKey`, returns option chosen by this `PubKey` for this validator (`nil` if `PubKey` has not voted under this validator)
- `ValidatorGovInfos`: A mapping `map[[]byte]ValidatorGovInfo` of validator's governance infos indexed by `<proposalID>:<validatorGovPubKey>`. Returns `nil` if proposal has not entered voting period or if `PubKey` was not the governance public key of a validator when proposal entered voting period.
@ -201,8 +202,6 @@ type ValidatorGovInfo struct {
**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 `CurrentBlock == VotingStartBlock + InitProcedure.VotingPeriod`. If it is, then the application checks if validators in `InitVotingPowerList` have voted and, if not, applies `GovernancePenalty`. After that proposal is ejected from `ProposalProcessingQueue` and the next element of the queue is evaluated. Note that if a proposal is urgent and accepted under the special condition, its `ProposalID` must be ejected from `ProposalProcessingQueue`.
*Note: Actual data structure may differ*
And the pseudocode for the `ProposalProcessingQueue`:
```
@ -229,7 +228,9 @@ And the pseudocode for the `ProposalProcessingQueue`:
ProposalProcessingQueue.pop()
checkProposal()
else if (CurrentBlock == proposal.VotingStartBlock + initProcedure.VotingPeriod)
else if (CurrentBlock == proposal.VotingStartBlock + initProcedure.VotingPeriod)
activeProcedure = load(store, Procedures, ActiveProcedureNumber)
for each validator in CurrentBondedValidators
validatorGovInfo = load(store, ValidatorGovInfos, validator.GovPubKey)
@ -240,7 +241,7 @@ And the pseudocode for the `ProposalProcessingQueue`:
validatorOption = load(store, Options, validator.GovPubKey)
if (validatorOption == nil)
// validator did not vote
slash validator by ActiveProcedure.GovernancePenalty
slash validator by activeProcedure.GovernancePenalty
ProposalProcessingQueue.pop()
checkProposal()
@ -251,7 +252,6 @@ And the pseudocode for the `ProposalProcessingQueue`:
#### Proposal Submission
Proposals can be submitted by any Atom holder via a `TxGovSubmitProposal` transaction.
```Go
@ -307,8 +307,9 @@ upon receiving txGovSubmitProposal from sender do
proposal.SubmitBlock = CurrentBlock
store(Deposits, <proposalID>:<sender>, txGovSubmitProposal.InitialDeposit)
activeProcedure = load(store, Procedures, ActiveProcedureNumber)
if (txGovSubmitProposal.InitialDeposit < ActiveProcedure.MinDeposit) then
if (txGovSubmitProposal.InitialDeposit < activeProcedure.MinDeposit) then
// MinDeposit is not reached
proposal.VotingStartBlock = -1
@ -320,7 +321,7 @@ upon receiving txGovSubmitProposal from sender do
proposal.VotingStartBlock = CurrentBlock
proposal.InitTotalVotingPower = TotalVotingPower
proposal.InitProcedureNumber = ActiveProcedure.ProcedureNumber
proposal.InitProcedureNumber = ActiveProcedureNumber
for each validator in CurrentBondedValidators
// Store voting power of each bonded validator
@ -379,19 +380,20 @@ upon receiving txGovDeposit from sender do
throw
else
if (txGovDeposit.Deposit <= 0 OR sender.AtomBalance < txGovDeposit.Deposit)
if (txGovDeposit.Deposit <= 0) OR (sender.AtomBalance < txGovDeposit.Deposit)
// deposit is negative or null OR sender has insufficient funds
throw
else
if (proposal.Deposit >= ActiveProcedure.MinDeposit) then
activeProcedure = load(store, Procedures, ActiveProcedureNumber)
if (proposal.Deposit >= activeProcedure.MinDeposit) then
// MinDeposit was reached
throw
else
if (CurrentBlock >= proposal.SubmitBlock + ActiveProcedure.MaxDepositPeriod) then
if (CurrentBlock >= proposal.SubmitBlock + activeProcedure.MaxDepositPeriod) then
// Maximum deposit period reached
throw
@ -404,21 +406,23 @@ upon receiving txGovDeposit from sender do
if (deposit == nil)
// sender has never deposited on this proposal
store(Deposits, <txGovDeposit.ProposalID>:<sender>, deposit)
else
// sender has already deposited on this proposal
newDeposit = deposit + txGovDeposit.Deposit
store(Deposits, <txGovDeposit.ProposalID>:<sender>, newDeposit)
proposal.Deposit += txGovDeposit.Deposit
if (proposal.Deposit >= ActiveProcedure.MinDeposit) then
if (proposal.Deposit >= activeProcedure.MinDeposit) then
// MinDeposit is reached, vote opens
proposal.VotingStartBlock = CurrentBlock
proposal.InitTotalVotingPower = TotalVotingPower
proposal.InitProcedureNumber = ActiveProcedure.ProcedureNumber
proposal.InitProcedureNumber = ActiveProcedureNumber
for each validator in CurrentBondedValidators
// Store voting power of each bonded validator
@ -476,16 +480,17 @@ And the associated pseudocode
throw
else
if deposit <= 0
if (deposit <= 0)
// deposit has already been claimed
throw
else
if proposal.VotingStartBlock <= 0
if (proposal.VotingStartBlock <= 0)
// Vote never started
if (CurrentBlock <= proposal.SubmitBlock + ActiveProcedure.MaxDepositPeriod)
activeProcedure = load(store, Procedures, ActiveProcedureNumber)
if (CurrentBlock <= proposal.SubmitBlock + activeProcedure.MaxDepositPeriod)
// MaxDepositPeriod is not reached
throw
@ -563,7 +568,7 @@ Next is a pseudocode proposal of the way `TxGovVote` transactions can be handled
validator = load(store, Validators, txGovVote.ValidatorPubKey)
if !initProcedure.OptionSet.includes(txGovVote.Option) OR
validator == nil) then
(validator == nil) then
// Throws if
// Option is not in Option Set of procedure that was active when vote opened OR if