Skip to main content

Messages

Proposal Submission

Proposals can be submitted by any account via a MsgSubmitProposal transaction.

+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/gov/v1beta1/tx.proto#L24-L39

The Content of a MsgSubmitProposal message must have an appropriate router set in the governance module.

State modifications:

  • Generate new proposalID
  • Create new Proposal
  • Initialise Proposals attributes
  • Decrease balance of sender by InitialDeposit
  • If MinDeposit is reached:
    • Push proposalID in ProposalProcessingQueue
  • Transfer InitialDeposit from the Proposer to the governance ModuleAccount

A MsgSubmitProposal transaction can be handled according to the following pseudocode.

// PSEUDOCODE //
// Check if MsgSubmitProposal is valid. If it is, create proposal //

upon receiving txGovSubmitProposal from sender do

if !correctlyFormatted(txGovSubmitProposal)
// check if proposal is correctly formatted. Includes fee payment.
throw

initialDeposit = txGovSubmitProposal.InitialDeposit
if (initialDeposit.Atoms <= 0) OR (sender.AtomBalance < initialDeposit.Atoms)
// InitialDeposit is negative or null OR sender has insufficient funds
throw

if (txGovSubmitProposal.Type != ProposalTypePlainText) OR (txGovSubmitProposal.Type != ProposalTypeSoftwareUpgrade)

sender.AtomBalance -= initialDeposit.Atoms

depositParam = load(GlobalParams, 'DepositParam')

proposalID = generate new proposalID
proposal = NewProposal()

proposal.Title = txGovSubmitProposal.Title
proposal.Description = txGovSubmitProposal.Description
proposal.Type = txGovSubmitProposal.Type
proposal.TotalDeposit = initialDeposit
proposal.SubmitTime = <CurrentTime>
proposal.DepositEndTime = <CurrentTime>.Add(depositParam.MaxDepositPeriod)
proposal.Deposits.append({initialDeposit, sender})
proposal.Submitter = sender
proposal.YesVotes = 0
proposal.NoVotes = 0
proposal.NoWithVetoVotes = 0
proposal.AbstainVotes = 0
proposal.CurrentStatus = ProposalStatusOpen

store(Proposals, <proposalID|'proposal'>, proposal) // Store proposal in Proposals mapping
return proposalID

Deposit

Once a proposal is submitted, if Proposal.TotalDeposit < ActiveParam.MinDeposit, Atom holders can send MsgDeposit transactions to increase the proposal's deposit.

+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/gov/v1beta1/tx.proto#L61-L72

State modifications:

  • Decrease balance of sender by deposit
  • Add deposit of sender in proposal.Deposits
  • Increase proposal.TotalDeposit by sender's deposit
  • If MinDeposit is reached:
    • Push proposalID in ProposalProcessingQueueEnd
  • Transfer Deposit from the proposer to the governance ModuleAccount

A MsgDeposit transaction has to go through a number of checks to be valid. These checks are outlined in the following pseudocode.

// PSEUDOCODE //
// Check if MsgDeposit 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.

if !correctlyFormatted(txGovDeposit)
throw

proposal = load(Proposals, <txGovDeposit.ProposalID|'proposal'>) // proposal is a const key, proposalID is variable

if (proposal == nil)
// There is no proposal for this proposalID
throw

if (txGovDeposit.Deposit.Atoms <= 0) OR (sender.AtomBalance < txGovDeposit.Deposit.Atoms) OR (proposal.CurrentStatus != ProposalStatusOpen)

// deposit is negative or null
// OR sender has insufficient funds
// OR proposal is not open for deposit anymore

throw

depositParam = load(GlobalParams, 'DepositParam')

if (CurrentBlock >= proposal.SubmitBlock + depositParam.MaxDepositPeriod)
proposal.CurrentStatus = ProposalStatusClosed

else
// sender can deposit
sender.AtomBalance -= txGovDeposit.Deposit.Atoms

proposal.Deposits.append({txGovVote.Deposit, sender})
proposal.TotalDeposit.Plus(txGovDeposit.Deposit)

if (proposal.TotalDeposit >= depositParam.MinDeposit)
// MinDeposit is reached, vote opens

proposal.VotingStartBlock = CurrentBlock
proposal.CurrentStatus = ProposalStatusActive
ProposalProcessingQueue.push(txGovDeposit.ProposalID)

store(Proposals, <txGovVote.ProposalID|'proposal'>, proposal)

Vote

Once ActiveParam.MinDeposit is reached, voting period starts. From there, bonded Atom holders are able to send MsgVote transactions to cast their vote on the proposal.

+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/gov/v1beta1/tx.proto#L46-L56

State modifications:

  • Record Vote of sender

Note: Gas cost for this message has to take into account the future tallying of the vote in EndBlocker

Next is a pseudocode outline of the way MsgVote transactions are handled:

  // PSEUDOCODE //
// Check if MsgVote is valid. If it is, count vote//

upon receiving txGovVote from sender do
// check if proposal is correctly formatted. Includes fee payment.

if !correctlyFormatted(txGovDeposit)
throw

proposal = load(Proposals, <txGovDeposit.ProposalID|'proposal'>)

if (proposal == nil)
// There is no proposal for this proposalID
throw


if (proposal.CurrentStatus == ProposalStatusActive)


// Sender can vote if
// Proposal is active
// Sender has some bonds

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.