Removed stores, change address to PubKey, fixes, ...
This commit is contained in:
parent
66c89143be
commit
9820f5b45c
@ -33,20 +33,16 @@ When a proposal is submitted, it has to be accompanied 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 proposal's
|
||||
deposit reaches `MinDeposit`, it enters voting period.
|
||||
proposal's deposit by sending a `TxGovDeposit` transaction. Once the proposal's deposit reaches `MinDeposit`, it enters voting period.
|
||||
|
||||
If proposal's deposit does not reach `MinDeposit` before `MaxDepositPeriod`, proposal closes and nobody can deposit on it anymore.
|
||||
|
||||
### Deposit refund
|
||||
|
||||
There are two instances where Atom holders that deposited can claim back their
|
||||
deposit:
|
||||
There is one instance where Atom holders that deposits can be refunded:
|
||||
* If the proposal is accepted.
|
||||
* If the proposal's deposit does not reach `MinDeposit` for a period longer
|
||||
than `MaxDepositPeriod` (initial value: 2 months). Then the proposal is
|
||||
considered closed and nobody can deposit on it anymore.
|
||||
|
||||
In such instances, Atom holders that deposited can send a `TxGovClaimDeposit`
|
||||
transaction to retrieve their share of the deposit.
|
||||
Then, deposits will automatically be refunded to their respective depositer.
|
||||
|
||||
### Proposal types
|
||||
|
||||
@ -162,9 +158,9 @@ period` is over), then the validator will automatically be partially slashed by
|
||||
That is because the proposal will close as soon as the ratio exceeds 2:3,
|
||||
making it mechanically impossible for some validators to vote on it.
|
||||
|
||||
### Governance key and governance address
|
||||
### Governance address
|
||||
|
||||
Later, we may add permissionned keys that could only sign txs from certain modules. For the MVP, the `Governance PubKey` will be the main validator PubKey generated at account creation. This PubKey corresponds to a different PrivKey than the Tendermint PrivKey which is responsible for signing consensus messages. Validators thus do not have to sign governance transactions with the sensitive Tendermint PrivKey.
|
||||
Later, we may add permissionned keys that could only sign txs from certain modules. For the MVP, the `Governance address` will be the main validator address generated at account creation. This address corresponds to a different PrivKey than the Tendermint PrivKey which is responsible for signing consensus messages. Validators thus do not have to sign governance transactions with the sensitive Tendermint PrivKey.
|
||||
|
||||
## Software Upgrade
|
||||
|
||||
|
||||
@ -24,6 +24,28 @@ type Procedure struct {
|
||||
}
|
||||
```
|
||||
|
||||
The current active procedure is stored in a global `params` KVStore.
|
||||
|
||||
### Deposit
|
||||
|
||||
```go
|
||||
type Deposit struct {
|
||||
Amount sdk.Coins // sAmount of coins deposited by depositer
|
||||
Depositer crypto.address // Address of depositer
|
||||
}
|
||||
```
|
||||
|
||||
### Votes
|
||||
|
||||
```go
|
||||
type Votes struct {
|
||||
YesVotes int64
|
||||
NoVote int64
|
||||
NoWithVetoVotes int64
|
||||
AbstainVotes int64
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### Proposals
|
||||
|
||||
@ -34,12 +56,15 @@ type Proposal struct {
|
||||
Title string // Title of the proposal
|
||||
Description string // Description of the proposal
|
||||
Type string // Type of proposal. Initial set {PlainTextProposal, SoftwareUpgradeProposal}
|
||||
Deposit int64 // Current deposit on this proposal. Initial value is set at InitialDeposit
|
||||
TotalDeposit sdk.Coins // Current deposit on this proposal. Initial value is set at InitialDeposit
|
||||
Deposits []Deposit // List of deposits on the proposal
|
||||
SubmitBlock int64 // Height of the block where TxGovSubmitProposal was included
|
||||
|
||||
VotingStartBlock int64 // Height of the block where MinDeposit was reached. -1 if MinDeposit is not reached
|
||||
InitTotalVotingPower int64 // Total voting power when proposal enters voting period (default 0)
|
||||
InitProcedureNumber int16 // Procedure number of the active procedure when proposal enters voting period (default -1)
|
||||
InitProcedure Procedure // Active Procedure when proposal enters voting period
|
||||
|
||||
Votes Votes // Total votes for each option
|
||||
}
|
||||
```
|
||||
|
||||
@ -56,24 +81,16 @@ type ValidatorGovInfo struct {
|
||||
|
||||
*Stores are KVStores in the multistore. The key to find the store is the first parameter in the list*
|
||||
|
||||
* `Procedures`: a mapping `map[int16]Procedure` of procedures indexed by their
|
||||
`ProcedureNumber`. First ever procedure is found at index '1'. Index '0' is reserved for parameter `ActiveProcedureNumber` which returns the number of the current procedure.
|
||||
|
||||
* `Proposals`: A mapping `map[int64]Proposal` of proposals indexed by their
|
||||
`proposalID`
|
||||
* `Votes`: A mapping `map[[]byte]int64` of votes indexed by `<proposalID>:<option>` as `[]byte`. Given a `proposalID` and an `option`, returns votes for that option.
|
||||
* `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)
|
||||
`<proposalID>:<voterAddress>:<validatorAddress>` as `[]byte`. Given a
|
||||
`proposalID`, an `address` and a validator's `address`, returns option chosen by this `address` for this validator (`nil` if `address` has not voted under this validator)
|
||||
* `ValidatorGovInfos`: A mapping `map[[]byte]ValidatorGovInfo` of validator's
|
||||
governance infos indexed by `<proposalID>:<validatorPubKey>`. Returns
|
||||
`nil` if proposal has not entered voting period or if `PubKey` was not the
|
||||
public key of a validator when proposal entered voting period.
|
||||
governance infos indexed by `<proposalID>:<validatorAddress>`. Returns
|
||||
`nil` if proposal has not entered voting period or if `address` was not the
|
||||
address of a validator when proposal entered voting period.
|
||||
|
||||
For pseudocode purposes, here are the two function we will use to read or write in stores:
|
||||
|
||||
@ -88,9 +105,9 @@ For pseudocode purposes, here are the two function we will use to read or write
|
||||
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,
|
||||
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.
|
||||
Note that if a proposal is accepted under the special condition,
|
||||
its `ProposalID` must be ejected from `ProposalProcessingQueue`.
|
||||
|
||||
And the pseudocode for the `ProposalProcessingQueue`:
|
||||
@ -109,33 +126,56 @@ And the pseudocode for the `ProposalProcessingQueue`:
|
||||
else
|
||||
proposalID = ProposalProcessingQueue.Peek()
|
||||
proposal = load(Proposals, proposalID)
|
||||
initProcedure = load(Procedures, proposal.InitProcedureNumber)
|
||||
yesVotes = load(Votes, <proposalID>:<'Yes'>)
|
||||
|
||||
if (yesVotes/proposal.InitTotalVotingPower >= 2/3)
|
||||
if (proposal.Votes.YesVotes/proposal.InitTotalVotingPower >= 2/3)
|
||||
|
||||
// proposal was urgent and accepted under the special condition
|
||||
// no punishment
|
||||
// refund deposits
|
||||
|
||||
ProposalProcessingQueue.pop()
|
||||
|
||||
newDeposits = new []Deposits
|
||||
|
||||
for each (amount, depositer) in proposal.Deposits
|
||||
newDeposits.append[{0, depositer}]
|
||||
depositer.AtomBalance += amount
|
||||
|
||||
proposal.Deposits = newDeposits
|
||||
store(Proposals, <proposalID>, proposal)
|
||||
|
||||
checkProposal()
|
||||
|
||||
else if (CurrentBlock == proposal.VotingStartBlock + initProcedure.VotingPeriod)
|
||||
else if (CurrentBlock == proposal.VotingStartBlock + proposal.Procedure.VotingPeriod)
|
||||
|
||||
activeProcedureNumber = load(Procedures, '0')
|
||||
activeProcedure = load(Procedures, activeProcedureNumber)
|
||||
ProposalProcessingQueue.pop()
|
||||
activeProcedure = load(params, 'ActiveProcedure')
|
||||
|
||||
for each validator in CurrentBondedValidators
|
||||
validatorGovInfo = load(multistore, ValidatorGovInfos, validator.PubKey)
|
||||
validatorGovInfo = load(ValidatorGovInfos, <proposalID>:<validator.address>)
|
||||
|
||||
if (validatorGovInfo.InitVotingPower != nil)
|
||||
// validator was bonded when vote started
|
||||
|
||||
validatorOption = load(Options, validator.PubKey)
|
||||
validatorOption = load(Options, <proposalID>:<validator.address><validator.address>)
|
||||
if (validatorOption == nil)
|
||||
// validator did not vote
|
||||
slash validator by activeProcedure.GovernancePenalty
|
||||
|
||||
ProposalProcessingQueue.pop()
|
||||
|
||||
if((proposal.Votes.YesVotes/(proposal.Votes.YesVotes + proposal.Votes.NoVotes + proposal.Votes.NoWithVetoVotes)) > 0.5 AND (proposal.Votes.NoWithVetoVotes/(proposal.Votes.YesVotes + proposal.Votes.NoVotes + proposal.Votes.NoWithVetoVotes) < 1/3))
|
||||
|
||||
// proposal was accepted at the end of the voting period
|
||||
// refund deposits
|
||||
|
||||
newDeposits = new []Deposits
|
||||
|
||||
for each (amount, depositer) in proposal.Deposits
|
||||
newDeposits.append[{0, depositer}]
|
||||
depositer.AtomBalance += amount
|
||||
|
||||
proposal.Deposits = newDeposits
|
||||
store(Proposals, <proposalID>, proposal)
|
||||
|
||||
checkProposal()
|
||||
```
|
||||
@ -20,7 +20,6 @@ type TxGovSubmitProposal struct {
|
||||
* Generate new `proposalID`
|
||||
* Create new `Proposal`
|
||||
* Initialise `Proposals` attributes
|
||||
* Store sender's deposit in `Deposits`
|
||||
* Decrease balance of sender by `InitialDeposit`
|
||||
* If `MinDeposit` is reached:
|
||||
* Push `proposalID` in `ProposalProcessingQueueEnd`
|
||||
@ -55,35 +54,37 @@ upon receiving txGovSubmitProposal from sender do
|
||||
proposal.Title = txGovSubmitProposal.Title
|
||||
proposal.Description = txGovSubmitProposal.Description
|
||||
proposal.Type = txGovSubmitProposal.Type
|
||||
proposal.Deposit = txGovSubmitProposal.InitialDeposit
|
||||
proposal.TotalDeposit = txGovSubmitProposal.InitialDeposit
|
||||
proposal.SubmitBlock = CurrentBlock
|
||||
proposal.Deposits.append({InitialDeposit, sender})
|
||||
proposal.Votes.YesVotes = 0
|
||||
proposal.Votes.NoVotes = 0
|
||||
proposal.Votes.NoWithVetoVotes = 0
|
||||
proposal.Votes.AbstainVotes = 0
|
||||
|
||||
store(Deposits, <proposalID>:<sender>, txGovSubmitProposal.InitialDeposit)
|
||||
activeProcedureNumber = load(Procedures, '0')
|
||||
activeProcedure = load(Procedures, activeProcedureNumber)
|
||||
activeProcedure = load(params, 'ActiveProcedure')
|
||||
|
||||
if (txGovSubmitProposal.InitialDeposit < activeProcedure.MinDeposit) then
|
||||
// MinDeposit is not reached
|
||||
|
||||
proposal.VotingStartBlock = -1
|
||||
proposal.InitTotalVotingPower = 0
|
||||
proposal.InitProcedureNumber = -1
|
||||
|
||||
else
|
||||
// MinDeposit is reached
|
||||
|
||||
proposal.VotingStartBlock = CurrentBlock
|
||||
proposal.InitTotalVotingPower = TotalVotingPower
|
||||
proposal.InitProcedureNumber = ActiveProcedureNumber
|
||||
proposal.InitProcedure = activeProcedure
|
||||
|
||||
for each validator in CurrentBondedValidators
|
||||
// Store voting power of each bonded validator
|
||||
|
||||
validatorGovInfo = NewValidatorGovInfo()
|
||||
validatorGovInfo = new ValidatorGovInfo
|
||||
validatorGovInfo.InitVotingPower = validator.VotingPower
|
||||
validatorGovInfo.Minus = 0
|
||||
|
||||
store(ValidatorGovInfos, <proposalID>:<validator.PubKey>, validatorGovInfo)
|
||||
store(ValidatorGovInfos, <proposalID>:<validator.Address>, validatorGovInfo)
|
||||
|
||||
ProposalProcessingQueue.push(proposalID)
|
||||
|
||||
@ -94,7 +95,7 @@ upon receiving txGovSubmitProposal from sender do
|
||||
### Deposit
|
||||
|
||||
Once a proposal is submitted, if
|
||||
`Proposal.Deposit < ActiveProcedure.MinDeposit`, Atom holders can send
|
||||
`Proposal.TotalDeposit < ActiveProcedure.MinDeposit`, Atom holders can send
|
||||
`TxGovDeposit` transactions to increase the proposal's deposit.
|
||||
|
||||
```go
|
||||
@ -106,8 +107,8 @@ type TxGovDeposit struct {
|
||||
|
||||
**State modifications:**
|
||||
* Decrease balance of sender by `deposit`
|
||||
* Initialize or increase `deposit` of sender in `Deposits`
|
||||
* Increase `proposal.Deposit` by sender's `deposit`
|
||||
* Add `deposit` of sender in `proposal.Deposits`
|
||||
* Increase `proposal.TotalDeposit` by sender's `deposit`
|
||||
* If `MinDeposit` is reached:
|
||||
* Push `proposalID` in `ProposalProcessingQueueEnd`
|
||||
* Store each validator's voting power in `ValidatorGovInfos`
|
||||
@ -140,9 +141,9 @@ upon receiving txGovDeposit from sender do
|
||||
throw
|
||||
|
||||
else
|
||||
activeProcedureNumber = load(Procedures, '0')
|
||||
activeProcedure = load(Procedures, activeProcedureNumber)
|
||||
if (proposal.Deposit >= activeProcedure.MinDeposit) then
|
||||
activeProcedure = load(params, 'ActiveProcedure')
|
||||
|
||||
if (proposal.TotalDeposit >= activeProcedure.MinDeposit) then
|
||||
// MinDeposit was reached
|
||||
|
||||
throw
|
||||
@ -157,27 +158,16 @@ upon receiving txGovDeposit from sender do
|
||||
// sender can deposit
|
||||
|
||||
sender.AtomBalance -= txGovDeposit.Deposit
|
||||
deposit = load(Deposits, <txGovDeposit.ProposalID>:<sender>)
|
||||
|
||||
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
|
||||
proposal.Deposits.append({txGovVote.Deposit, sender})
|
||||
proposal.TotalDeposit += txGovDeposit.Deposit
|
||||
|
||||
if (proposal.Deposit >= activeProcedure.MinDeposit) then
|
||||
if (proposal.TotalDeposit >= activeProcedure.MinDeposit) then
|
||||
// MinDeposit is reached, vote opens
|
||||
|
||||
proposal.VotingStartBlock = CurrentBlock
|
||||
proposal.InitTotalVotingPower = TotalVotingPower
|
||||
proposal.InitProcedureNumber = ActiveProcedureNumber
|
||||
proposal.InitProcedure = activeProcedure
|
||||
|
||||
for each validator in CurrentBondedValidators
|
||||
// Store voting power of each bonded validator
|
||||
@ -186,98 +176,11 @@ upon receiving txGovDeposit from sender do
|
||||
validatorGovInfo.InitVotingPower = validator.VotingPower
|
||||
validatorGovInfo.Minus = 0
|
||||
|
||||
store(ValidatorGovInfos, <proposalID>:<validator.PubKey>, validatorGovInfo)
|
||||
store(ValidatorGovInfos, <proposalID>:<validator.Address>, validatorGovInfo)
|
||||
|
||||
ProposalProcessingQueue.push(txGovDeposit.ProposalID)
|
||||
|
||||
store(Proposals, <txGovVote.ProposalID>, proposal)
|
||||
```
|
||||
|
||||
### Claim deposit
|
||||
|
||||
Finally, if the proposal is accepted or `MinDeposit` was not reached before the
|
||||
end of the `MaximumDepositPeriod`, then Atom holders can send
|
||||
`TxGovClaimDeposit` transaction to claim their deposits.
|
||||
|
||||
```go
|
||||
type TxGovClaimDeposit struct {
|
||||
ProposalID int64
|
||||
}
|
||||
```
|
||||
|
||||
**State modifications:**
|
||||
If conditions are met, reimburse the deposit, i.e.
|
||||
* Increase `AtomBalance` of sender by `deposit`
|
||||
* Set `deposit` of sender in `DepositorsList` to 0
|
||||
|
||||
And the associated pseudocode.
|
||||
|
||||
```go
|
||||
// PSEUDOCODE //
|
||||
/* Check if TxGovClaimDeposit is valid. If vote never started and MaxDepositPeriod is reached or if vote started and proposal was accepted, return deposit */
|
||||
|
||||
upon receiving txGovClaimDeposit from sender do
|
||||
// check if proposal is correctly formatted. Includes fee payment.
|
||||
|
||||
if !correctlyFormatted(txGovClaimDeposit) then
|
||||
throw
|
||||
|
||||
else
|
||||
proposal = load(Proposals, txGovDeposit.ProposalID)
|
||||
|
||||
if (proposal == nil) then
|
||||
// There is no proposal for this proposalID
|
||||
|
||||
throw
|
||||
|
||||
else
|
||||
deposit = load(Deposits, <txGovClaimDeposit.ProposalID>:<sender>)
|
||||
|
||||
if (deposit == nil)
|
||||
// sender has not deposited on this proposal
|
||||
|
||||
throw
|
||||
|
||||
else
|
||||
if (deposit <= 0)
|
||||
// deposit has already been claimed
|
||||
|
||||
throw
|
||||
|
||||
else
|
||||
if (proposal.VotingStartBlock <= 0)
|
||||
// Vote never started
|
||||
|
||||
activeProcedureNumber = load(Procedures, '0')
|
||||
activeProcedure = load(Procedures, ActiveProcedureNumber)
|
||||
if (CurrentBlock <= proposal.SubmitBlock + activeProcedure.MaxDepositPeriod)
|
||||
// MaxDepositPeriod is not reached
|
||||
|
||||
throw
|
||||
|
||||
else
|
||||
// MaxDepositPeriod is reached
|
||||
// Set sender's deposit to 0 and refund
|
||||
|
||||
store(Deposits, <txGovClaimDeposit.ProposalID>:<sender>, 0)
|
||||
sender.AtomBalance += deposit
|
||||
|
||||
else
|
||||
// Vote started
|
||||
|
||||
initProcedure = load(Procedures, proposal.InitProcedureNumber)
|
||||
yesVotes = load(Votes, <txGovClaimDeposi.ProposalIDt>:<'Yes'>)
|
||||
noVotes = load(Votes, <txGovClaimDeposit.ProposalID>:<'No'>)
|
||||
noWithVetoVotes = load(Votes, <txGovClaimDeposit.ProposalID>:<'NoWithVeto'>)
|
||||
|
||||
if (yesVotes/proposal.InitTotalVotingPower >= 2/3) OR ((CurrentBlock > proposal.VotingStartBlock + initProcedure.VotingPeriod) AND (noWithVetoVotes/(yesVotes+noVotes+noWithVetoVotes)) < 1/3) AND (yesVotes/(yesVotes+noVotes+noWithVetoVotes)) > 1/2)) then
|
||||
|
||||
// Proposal was accepted either because
|
||||
// pecial condition was met OR
|
||||
// Voting period ended and vote satisfies threshold
|
||||
|
||||
store(Deposits, <txGovClaimDeposit.ProposalID>:<sender>, 0)
|
||||
sender.AtomBalance += deposit
|
||||
store(Proposals, txGovVote.ProposalID, proposal)
|
||||
```
|
||||
|
||||
### Vote
|
||||
@ -290,7 +193,7 @@ vote on the proposal.
|
||||
type TxGovVote struct {
|
||||
ProposalID int64 // proposalID of the proposal
|
||||
Option string // option from OptionSet chosen by the voter
|
||||
ValidatorPubKey crypto.PubKey // PubKey of the validator voter wants to tie its vote to
|
||||
ValidatorAddress crypto.address // Address of the validator voter wants to tie its vote to
|
||||
}
|
||||
```
|
||||
|
||||
@ -298,19 +201,19 @@ vote on the proposal.
|
||||
* If sender is not a validator and validator has not voted, initialize or
|
||||
increase minus of validator by sender's `voting power`
|
||||
* If sender is not a validator and validator has voted, decrease
|
||||
`Votes['validatorOption']` by sender's `voting power`
|
||||
* If sender is not a validator, increase `Votes['txGovVote.Option']`
|
||||
votes of `validatorOption` by sender's `voting power`
|
||||
* If sender is not a validator, increase votes of `txGovVote.Option`
|
||||
by sender's `voting power`
|
||||
* If sender is a validator, increase `Votes['txGovVote.Option']` by
|
||||
validator's `InitialVotingPower - minus` (`minus` can be equal to 0)
|
||||
* If sender is a validator, increase votes of `txGovVote.Option` by
|
||||
validator's `InitVotingPower - minus` (`minus` can be equal to 0)
|
||||
|
||||
Votes need to be tied to a validator in order to compute validator's voting
|
||||
power. If a delegator is bonded to multiple validators, it will have to send
|
||||
one transaction per validator (the UI should facilitate this so that multiple
|
||||
transactions can be sent in one "vote flow"). If the sender is the validator
|
||||
itself, then it will input its own GovernancePubKey as `ValidatorPubKey`
|
||||
itself, then it will input its own address as `ValidatorAddress`
|
||||
|
||||
Next is a pseudocode proposal of the way `TxGovVote` transactions can be
|
||||
Next is a pseudocode proposal of the way `TxGovVote` transactions are
|
||||
handled:
|
||||
|
||||
```go
|
||||
@ -332,46 +235,43 @@ handled:
|
||||
throw
|
||||
|
||||
else
|
||||
initProcedure = load(Procedures, proposal.InitProcedureNumber) // get procedure that was active when vote opened
|
||||
validator = load(Validators, txGovVote.ValidatorPubKey)
|
||||
validator = load(CurrentValidators, txGovVote.ValidatorAddress)
|
||||
|
||||
if !initProcedure.OptionSet.includes(txGovVote.Option) OR
|
||||
if !proposal.InitProcedure.OptionSet.includes(txGovVote.Option) OR
|
||||
(validator == nil) then
|
||||
|
||||
// Throws if
|
||||
// Option is not in Option Set of procedure that was active when vote opened OR if
|
||||
// ValidatorPubKey is not the PubKey of a current validator
|
||||
// ValidatorAddress is not the address of a current validator
|
||||
|
||||
throw
|
||||
|
||||
else
|
||||
option = load(Options, <txGovVote.ProposalID>:<sender>:<txGovVote.ValidatorPubKey>)
|
||||
option = load(Options, <txGovVote.ProposalID>:<sender>:<txGovVote.ValidatorAddress>)
|
||||
|
||||
if (option != nil)
|
||||
// sender has already voted with the Atoms bonded to ValidatorPubKey
|
||||
// sender has already voted with the Atoms bonded to ValidatorAddress
|
||||
|
||||
throw
|
||||
|
||||
else
|
||||
yesVotes = load(Votes, <txGovVote.ProposalID>:<'Yes'>)
|
||||
|
||||
if (proposal.VotingStartBlock < 0) OR
|
||||
(CurrentBlock > proposal.VotingStartBlock + initProcedure.VotingPeriod) OR
|
||||
(proposal.VotingStartBlock < lastBondingBlock(sender, txGovVote.ValidatorPubKey) OR
|
||||
(proposal.VotingStartBlock < lastUnbondingBlock(sender, txGovVote.ValidatorPubKey) OR
|
||||
(yesVotes/proposal.InitTotalVotingPower >= 2/3) then
|
||||
(CurrentBlock > proposal.VotingStartBlock + proposal.InitProcedure.VotingPeriod) OR
|
||||
(proposal.VotingStartBlock < lastBondingBlock(sender, txGovVote.ValidatorAddress) OR
|
||||
(proposal.VotingStartBlock < lastUnbondingBlock(sender, txGovVote.Address) OR
|
||||
(proposal.Votes.YesVotes/proposal.InitTotalVotingPower >= 2/3) then
|
||||
|
||||
// Throws if
|
||||
// Vote has not started OR if
|
||||
// Vote had ended OR if
|
||||
// sender bonded Atoms to ValidatorPubKey after start of vote OR if
|
||||
// sender unbonded Atoms from ValidatorPubKey after start of vote OR if
|
||||
// sender bonded Atoms to ValidatorAddress after start of vote OR if
|
||||
// sender unbonded Atoms from ValidatorAddress after start of vote OR if
|
||||
// special condition is met, i.e. proposal is accepted and closed
|
||||
|
||||
throw
|
||||
|
||||
else
|
||||
validatorGovInfo = load(ValidatorGovInfos, <txGovVote.ProposalID>:<validator.ValidatorPubKey>)
|
||||
validatorGovInfo = load(ValidatorGovInfos, <txGovVote.ProposalID>:<validator.ValidatorAddress>)
|
||||
|
||||
if (validatorGovInfo == nil)
|
||||
// validator became validator after proposal entered voting period
|
||||
@ -381,41 +281,46 @@ handled:
|
||||
else
|
||||
// sender can vote, check if sender == validator and store sender's option in Options
|
||||
|
||||
store(Options, <txGovVote.ProposalID>:<sender>:<txGovVote.ValidatorPubKey>, txGovVote.Option)
|
||||
store(Options, <txGovVote.ProposalID>:<sender>:<txGovVote.ValidatorAddress>, txGovVote.Option)
|
||||
|
||||
if (sender != validator.PubKey)
|
||||
// Here, sender is not the PubKey of the validator whose PubKey is txGovVote.ValidatorPubKey
|
||||
if (sender != validator.address)
|
||||
// Here, sender is not the Address of the validator whose Address is txGovVote.ValidatorAddress
|
||||
|
||||
if sender does not have bonded Atoms to txGovVote.ValidatorPubKey then
|
||||
if sender does not have bonded Atoms to txGovVote.ValidatorAddress then
|
||||
// check in Staking module
|
||||
|
||||
throw
|
||||
|
||||
else
|
||||
validatorOption = load(Options, <txGovVote.ProposalID>:<sender>:<txGovVote.ValidatorPubKey)
|
||||
validatorOption = load(Options, <txGovVote.ProposalID>:<sender>:<txGovVote.ValidatorAddress>)
|
||||
|
||||
if (validatorOption == nil)
|
||||
// Validator has not voted already
|
||||
|
||||
validatorGovInfo.Minus += sender.bondedAmounTo(txGovVote.ValidatorPubKey)
|
||||
store(ValidatorGovInfos, <txGovVote.ProposalID>:<validator.ValidatorPubKey>, validatorGovInfo)
|
||||
validatorGovInfo.Minus += sender.bondedAmounTo(txGovVote.ValidatorAddress)
|
||||
store(ValidatorGovInfos, <txGovVote.ProposalID>:<validator.ValidatorAddress>, validatorGovInfo)
|
||||
|
||||
else
|
||||
// Validator has already voted
|
||||
// Reduce votes of option chosen by validator by sender's bonded Amount
|
||||
|
||||
validatorVotes = load(Votes, <txGovVote.ProposalID>:<'validatorOption'>)
|
||||
store(Votes, <txGovVote.ProposalID>:<'validatorOption'>, validatorVotes - sender.bondedAmountTo(txGovVote.ValidatorPubKey))
|
||||
proposal.Votes.validatorOption -= sender.bondedAmountTo(txGovVote.ValidatorAddress)
|
||||
|
||||
// increase votes of option chosen by sender by bonded Amount
|
||||
optionVotes = load(Votes, <txGovVote.ProposalID>:<txGovVote.Option>)
|
||||
store(Votes,<txGovVote.ProposalID>:<txGovVote.Option>, optionVotes + sender.bondedAmountTo(txGovVote.ValidatorPubKey))
|
||||
|
||||
senderOption = txGovVote.Option
|
||||
propoal.Votes.senderOption -= sender.bondedAmountTo(txGovVote.ValidatorAddress)
|
||||
|
||||
store(Proposals, txGovVote.ProposalID, proposal)
|
||||
|
||||
|
||||
else
|
||||
// sender is the PubKey of the validator whose main PubKey is txGovVote.ValidatorPubKey
|
||||
// sender is the address of the validator whose main Address is txGovVote.ValidatorAddress
|
||||
// i.e. sender == validator
|
||||
|
||||
optionVotes = load(Votes, <txGovVote.ProposalID>:<txGovVote.Option>)
|
||||
store(Votes,<txGovVote.ProposalID>:<txGovVote.Option>, optionVotes + (validatorGovInfo.InitVotingPower - validatorGovInfo.Minus))
|
||||
proposal.Votes.validatorOption += (validatorGovInfo.InitVotingPower - validatorGovInfo.Minus)
|
||||
|
||||
store(Proposals, txGovVote.ProposalID, proposal)
|
||||
|
||||
|
||||
```
|
||||
Loading…
Reference in New Issue
Block a user