github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/cosmos-sdk/x/gov/spec/03_messages.md (about)

     1  <!--
     2  order: 3
     3  -->
     4  
     5  # Messages
     6  
     7  ## Proposal Submission
     8  
     9  Proposals can be submitted by any Atom holder via a `TxGovSubmitProposal`
    10  transaction.
    11  
    12  ```go
    13  type TxGovSubmitProposal struct {
    14  	Content        Content
    15  	InitialDeposit sdk.Coins
    16  	Proposer       sdk.AccAddress
    17  }
    18  ```
    19  
    20  The `Content` of a `TxGovSubmitProposal` message must have an appropriate router
    21  set in the governance module.
    22  
    23  **State modifications:**
    24  * Generate new `proposalID`
    25  * Create new `Proposal`
    26  * Initialise `Proposals` attributes
    27  * Decrease balance of sender by `InitialDeposit`
    28  * If `MinDeposit` is reached:
    29    * Push `proposalID` in  `ProposalProcessingQueue`
    30  * Transfer `InitialDeposit` from the `Proposer` to the governance `ModuleAccount`
    31  
    32  A `TxGovSubmitProposal` transaction can be handled according to the following
    33  pseudocode.
    34  
    35  ```go
    36  // PSEUDOCODE //
    37  // Check if TxGovSubmitProposal is valid. If it is, create proposal //
    38  
    39  upon receiving txGovSubmitProposal from sender do
    40  
    41    if !correctlyFormatted(txGovSubmitProposal)
    42      // check if proposal is correctly formatted. Includes fee payment.
    43      throw
    44  
    45    initialDeposit = txGovSubmitProposal.InitialDeposit
    46    if (initialDeposit.Atoms <= 0) OR (sender.AtomBalance < initialDeposit.Atoms)
    47      // InitialDeposit is negative or null OR sender has insufficient funds
    48      throw
    49  
    50    if (txGovSubmitProposal.Type != ProposalTypePlainText) OR (txGovSubmitProposal.Type != ProposalTypeSoftwareUpgrade)
    51  
    52    sender.AtomBalance -= initialDeposit.Atoms
    53  
    54    depositParam = load(GlobalParams, 'DepositParam')
    55  
    56    proposalID = generate new proposalID
    57    proposal = NewProposal()
    58  
    59    proposal.Title = txGovSubmitProposal.Title
    60    proposal.Description = txGovSubmitProposal.Description
    61    proposal.Type = txGovSubmitProposal.Type
    62    proposal.TotalDeposit = initialDeposit
    63    proposal.SubmitTime = <CurrentTime>
    64    proposal.DepositEndTime = <CurrentTime>.Add(depositParam.MaxDepositPeriod)
    65    proposal.Deposits.append({initialDeposit, sender})
    66    proposal.Submitter = sender
    67    proposal.YesVotes = 0
    68    proposal.NoVotes = 0
    69    proposal.NoWithVetoVotes = 0
    70    proposal.AbstainVotes = 0
    71    proposal.CurrentStatus = ProposalStatusOpen
    72  
    73    store(Proposals, <proposalID|'proposal'>, proposal) // Store proposal in Proposals mapping
    74    return proposalID
    75  ```
    76  
    77  ## Deposit
    78  
    79  Once a proposal is submitted, if
    80  `Proposal.TotalDeposit < ActiveParam.MinDeposit`, Atom holders can send
    81  `TxGovDeposit` transactions to increase the proposal's deposit.
    82  
    83  ```go
    84  type TxGovDeposit struct {
    85    ProposalID    int64       // ID of the proposal
    86    Deposit       sdk.Coins   // Number of Atoms to add to the proposal's deposit
    87  }
    88  ```
    89  
    90  **State modifications:**
    91  * Decrease balance of sender by `deposit`
    92  * Add `deposit` of sender in `proposal.Deposits`
    93  * Increase `proposal.TotalDeposit` by sender's `deposit`
    94  * If `MinDeposit` is reached:
    95    * Push `proposalID` in  `ProposalProcessingQueueEnd`
    96  * Transfer `Deposit` from the `proposer` to the governance `ModuleAccount`
    97  
    98  A `TxGovDeposit` transaction has to go through a number of checks to be valid.
    99  These checks are outlined in the following pseudocode.
   100  
   101  ```go
   102  // PSEUDOCODE //
   103  // Check if TxGovDeposit is valid. If it is, increase deposit and check if MinDeposit is reached
   104  
   105  upon receiving txGovDeposit from sender do
   106    // check if proposal is correctly formatted. Includes fee payment.
   107  
   108    if !correctlyFormatted(txGovDeposit)
   109      throw
   110  
   111    proposal = load(Proposals, <txGovDeposit.ProposalID|'proposal'>) // proposal is a const key, proposalID is variable
   112  
   113    if (proposal == nil)
   114      // There is no proposal for this proposalID
   115      throw
   116  
   117    if (txGovDeposit.Deposit.Atoms <= 0) ORĀ (sender.AtomBalance < txGovDeposit.Deposit.Atoms) OR (proposal.CurrentStatus != ProposalStatusOpen)
   118  
   119      // deposit is negative or null
   120      // OR sender has insufficient funds
   121      // OR proposal is not open for deposit anymore
   122  
   123      throw
   124  
   125    depositParam = load(GlobalParams, 'DepositParam')
   126  
   127    if (CurrentBlock >= proposal.SubmitBlock + depositParam.MaxDepositPeriod)
   128      proposal.CurrentStatus = ProposalStatusClosed
   129  
   130    else
   131      // sender can deposit
   132      sender.AtomBalance -= txGovDeposit.Deposit.Atoms
   133  
   134      proposal.Deposits.append({txGovVote.Deposit, sender})
   135      proposal.TotalDeposit.Plus(txGovDeposit.Deposit)
   136  
   137      if (proposal.TotalDeposit >= depositParam.MinDeposit)
   138        // MinDeposit is reached, vote opens
   139  
   140        proposal.VotingStartBlock = CurrentBlock
   141        proposal.CurrentStatus = ProposalStatusActive
   142        ProposalProcessingQueue.push(txGovDeposit.ProposalID)
   143  
   144    store(Proposals, <txGovVote.ProposalID|'proposal'>, proposal)
   145  ```
   146  
   147  ## Vote
   148  
   149  Once `ActiveParam.MinDeposit` is reached, voting period starts. From there,
   150  bonded Atom holders are able to send `TxGovVote` transactions to cast their
   151  vote on the proposal.
   152  
   153  ```go
   154    type TxGovVote struct {
   155      ProposalID           int64         //  proposalID of the proposal
   156      Vote                 byte          //  option from OptionSet chosen by the voter
   157    }
   158  ```
   159  
   160  **State modifications:**
   161  * Record `Vote` of sender
   162  
   163  *Note: Gas cost for this message has to take into account the future tallying of the vote in EndBlocker*
   164  
   165  
   166  Next is a pseudocode proposal of the way `TxGovVote` transactions are
   167  handled:
   168  
   169  ```go
   170    // PSEUDOCODE //
   171    // Check if TxGovVote is valid. If it is, count vote//
   172  
   173    upon receiving txGovVote from sender do
   174      // check if proposal is correctly formatted. Includes fee payment.
   175  
   176      if !correctlyFormatted(txGovDeposit)
   177        throw
   178  
   179      proposal = load(Proposals, <txGovDeposit.ProposalID|'proposal'>)
   180  
   181      if (proposal == nil)
   182        // There is no proposal for this proposalID
   183        throw
   184  
   185  
   186      if  (proposal.CurrentStatus == ProposalStatusActive)
   187  
   188  
   189          // Sender can vote if
   190          // Proposal is active
   191          // Sender has some bonds
   192  
   193          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.
   194  ```