2018-02-26 07:35:09 -08:00
# Implementation (2/2)
2019-01-21 16:52:03 -08:00
## Messages
2018-02-26 07:35:09 -08:00
### Proposal Submission
2018-11-13 15:45:37 -08:00
Proposals can be submitted by any Atom holder via a `TxGovSubmitProposal`
2018-02-26 07:35:09 -08:00
transaction.
```go
type TxGovSubmitProposal struct {
Title string // Title of the proposal
Description string // Description of the proposal
2018-05-08 12:53:23 -07:00
Type ProposalType // Type of proposal
2018-06-04 08:20:07 -07:00
InitialDeposit sdk.Coins // Initial deposit paid by sender. Must be strictly positive.
2018-02-26 07:35:09 -08:00
}
```
**State modifications:**
* Generate new `proposalID`
* Create new `Proposal`
* Initialise `Proposals` attributes
* Decrease balance of sender by `InitialDeposit`
* If `MinDeposit` is reached:
2018-06-04 08:20:07 -07:00
* Push `proposalID` in `ProposalProcessingQueue`
2018-02-26 07:35:09 -08:00
2018-11-13 15:45:37 -08:00
A `TxGovSubmitProposal` transaction can be handled according to the following
2018-02-26 07:35:09 -08:00
pseudocode.
```go
// PSEUDOCODE //
// Check if TxGovSubmitProposal is valid. If it is, create proposal //
upon receiving txGovSubmitProposal from sender do
2018-11-13 15:45:37 -08:00
if !correctlyFormatted(txGovSubmitProposal)
2018-02-26 07:35:09 -08:00
// check if proposal is correctly formatted. Includes fee payment.
throw
2018-11-13 15:45:37 -08:00
initialDeposit = txGovSubmitProposal.InitialDeposit
if (initialDeposit.Atoms < = 0) OR (sender.AtomBalance < initialDeposit.Atoms )
2018-05-08 12:53:23 -07:00
// InitialDeposit is negative or null OR sender has insufficient funds
throw
2018-06-15 07:18:50 -07:00
if (txGovSubmitProposal.Type != ProposalTypePlainText) OR (txGovSubmitProposal.Type != ProposalTypeSoftwareUpgrade)
2018-11-13 15:45:37 -08:00
2018-06-04 08:20:07 -07:00
sender.AtomBalance -= initialDeposit.Atoms
2018-11-06 23:33:18 -08:00
2018-11-13 15:45:37 -08:00
depositParam = load(GlobalParams, 'DepositParam')
2018-05-08 12:53:23 -07:00
proposalID = generate new proposalID
proposal = NewProposal()
2018-11-13 15:45:37 -08:00
2018-05-08 12:53:23 -07:00
proposal.Title = txGovSubmitProposal.Title
proposal.Description = txGovSubmitProposal.Description
proposal.Type = txGovSubmitProposal.Type
proposal.TotalDeposit = initialDeposit
2018-11-06 23:33:18 -08:00
proposal.SubmitTime = < CurrentTime >
2018-11-13 15:45:37 -08:00
proposal.DepositEndTime = < CurrentTime > .Add(depositParam.MaxDepositPeriod)
2018-05-08 12:53:23 -07:00
proposal.Deposits.append({initialDeposit, sender})
proposal.Submitter = sender
2018-06-04 08:20:07 -07:00
proposal.YesVotes = 0
proposal.NoVotes = 0
proposal.NoWithVetoVotes = 0
proposal.AbstainVotes = 0
2018-11-06 23:33:18 -08:00
proposal.CurrentStatus = ProposalStatusOpen
2018-11-13 15:45:37 -08:00
2018-06-05 07:43:56 -07:00
store(Proposals, < proposalID | ' proposal ' > , proposal) // Store proposal in Proposals mapping
2018-05-08 12:53:23 -07:00
return proposalID
2018-02-26 07:35:09 -08:00
```
### Deposit
2018-11-13 15:45:37 -08:00
Once a proposal is submitted, if
`Proposal.TotalDeposit < ActiveParam.MinDeposit` , Atom holders can send
2018-02-26 07:35:09 -08:00
`TxGovDeposit` transactions to increase the proposal's deposit.
```go
type TxGovDeposit struct {
2018-06-04 08:20:07 -07:00
ProposalID int64 // ID of the proposal
Deposit sdk.Coins // Number of Atoms to add to the proposal's deposit
2018-02-26 07:35:09 -08:00
}
```
**State modifications:**
* Decrease balance of sender by `deposit`
2018-03-01 08:21:35 -08:00
* Add `deposit` of sender in `proposal.Deposits`
* Increase `proposal.TotalDeposit` by sender's `deposit`
2018-02-26 07:35:09 -08:00
* If `MinDeposit` is reached:
* Push `proposalID` in `ProposalProcessingQueueEnd`
2018-11-13 15:45:37 -08:00
A `TxGovDeposit` transaction has to go through a number of checks to be valid.
2018-02-26 07:35:09 -08:00
These checks are outlined in the following pseudocode.
```go
// PSEUDOCODE //
// Check if TxGovDeposit is valid. If it is, increase deposit and check if MinDeposit is reached
upon receiving txGovDeposit from sender do
// check if proposal is correctly formatted. Includes fee payment.
2018-11-13 15:45:37 -08:00
if !correctlyFormatted(txGovDeposit)
2018-02-26 07:35:09 -08:00
throw
2018-11-13 15:45:37 -08:00
2018-06-05 07:43:56 -07:00
proposal = load(Proposals, < txGovDeposit.ProposalID | ' proposal ' > ) // proposal is a const key, proposalID is variable
2018-02-26 07:35:09 -08:00
2018-11-13 15:45:37 -08:00
if (proposal == nil)
2018-05-08 12:53:23 -07:00
// There is no proposal for this proposalID
throw
2018-11-13 15:45:37 -08:00
2018-06-05 07:43:56 -07:00
if (txGovDeposit.Deposit.Atoms < = 0) OR (sender.AtomBalance < txGovDeposit.Deposit.Atoms ) OR ( proposal . CurrentStatus ! = ProposalStatusOpen )
2018-11-13 15:45:37 -08:00
// deposit is negative or null
2018-06-04 08:20:07 -07:00
// OR sender has insufficient funds
2018-06-05 07:43:56 -07:00
// OR proposal is not open for deposit anymore
2018-06-04 08:20:07 -07:00
2018-05-08 12:53:23 -07:00
throw
2018-11-13 15:45:37 -08:00
depositParam = load(GlobalParams, 'DepositParam')
2018-06-15 07:18:50 -07:00
2018-11-13 15:45:37 -08:00
if (CurrentBlock >= proposal.SubmitBlock + depositParam.MaxDepositPeriod)
2018-06-05 07:43:56 -07:00
proposal.CurrentStatus = ProposalStatusClosed
2018-05-08 12:53:23 -07:00
2018-06-05 07:43:56 -07:00
else
// sender can deposit
sender.AtomBalance -= txGovDeposit.Deposit.Atoms
proposal.Deposits.append({txGovVote.Deposit, sender})
proposal.TotalDeposit.Plus(txGovDeposit.Deposit)
2018-11-13 15:45:37 -08:00
if (proposal.TotalDeposit >= depositParam.MinDeposit)
2018-06-05 07:43:56 -07:00
// MinDeposit is reached, vote opens
2018-11-13 15:45:37 -08:00
2018-06-05 07:43:56 -07:00
proposal.VotingStartBlock = CurrentBlock
proposal.CurrentStatus = ProposalStatusActive
2018-11-13 15:45:37 -08:00
ProposalProcessingQueue.push(txGovDeposit.ProposalID)
2018-06-05 07:43:56 -07:00
store(Proposals, < txGovVote.ProposalID | ' proposal ' > , proposal)
2018-02-26 07:35:09 -08:00
```
### Vote
2018-11-13 15:45:37 -08:00
Once `ActiveParam.MinDeposit` is reached, voting period starts. From there,
bonded Atom holders are able to send `TxGovVote` transactions to cast their
2018-02-26 07:35:09 -08:00
vote on the proposal.
```go
type TxGovVote struct {
2018-06-05 07:43:56 -07:00
ProposalID int64 // proposalID of the proposal
2018-06-04 08:20:07 -07:00
Vote byte // option from OptionSet chosen by the voter
2018-02-26 07:35:09 -08:00
}
```
**State modifications:**
2018-06-04 08:20:07 -07:00
* Record `Vote` of sender
*Note: Gas cost for this message has to take into account the future tallying of the vote in EndBlocker*
2018-02-26 07:35:09 -08:00
2018-11-13 15:45:37 -08:00
Next is a pseudocode proposal of the way `TxGovVote` transactions are
2018-02-26 07:35:09 -08:00
handled:
```go
// PSEUDOCODE //
// Check if TxGovVote is valid. If it is, count vote//
2018-11-13 15:45:37 -08:00
2018-02-26 07:35:09 -08:00
upon receiving txGovVote from sender do
2018-11-13 15:45:37 -08:00
// check if proposal is correctly formatted. Includes fee payment.
if !correctlyFormatted(txGovDeposit)
2018-02-26 07:35:09 -08:00
throw
2018-11-13 15:45:37 -08:00
2018-06-05 07:43:56 -07:00
proposal = load(Proposals, < txGovDeposit.ProposalID | ' proposal ' > )
2018-02-26 07:35:09 -08:00
2018-11-13 15:45:37 -08:00
if (proposal == nil)
2018-05-08 12:53:23 -07:00
// There is no proposal for this proposalID
throw
2018-11-13 15:45:37 -08:00
2018-02-26 07:35:09 -08:00
2018-07-02 04:50:55 -07:00
if (proposal.CurrentStatus == ProposalStatusActive)
2018-02-26 07:35:09 -08:00
2018-03-01 08:21:35 -08:00
2018-06-07 03:30:49 -07:00
// Sender can vote if
// Proposal is active
// Sender has some bonds
2018-02-26 07:35:09 -08:00
2018-06-05 07:43:56 -07:00
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.
2018-05-08 12:53:23 -07:00
```